UNPKG

@enzedonline/quill-blot-formatter2

Version:

An update for quill-blot-formatter to make quilljs v2 compatible.

6 lines 78.2 kB
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});class A{formatter;toolbarButtons=[];debug;constructor(t){this.formatter=t,this.debug=this.formatter.options.debug||!1,this.debug&&console.debug("Action created:",this.constructor.name)}onCreate=()=>{};onDestroy=()=>{};onUpdate=()=>{}}class v extends A{static sendCaretBack=(t=1,e=!1)=>{const i=window.getSelection();if(i&&i.rangeCount>0){const o=i.getRangeAt(0),s=o.startContainer,n=o.startOffset;if(n>0)o.setStart(s,n-t);else if(s.previousSibling){const r=s.previousSibling;r.nodeType===Node.TEXT_NODE&&o.setStart(r,r.textContent?.length||0)}o.collapse(!0),i.removeAllRanges(),i.addRange(o),e&&console.debug("Caret moved back by",t,"characters")}};static placeCaretBeforeBlot=(t,e,i=!1)=>{const o=t.getIndex(e);t.setSelection(o,0,"user"),i&&console.debug("Caret placed before blot at index:",o,e)};static placeCaretAfterBlot=(t,e,i=!1)=>{t.setSelection(null),t.root.focus();const o=t.getIndex(e),s=t.getLength();o+1>=s-1?(t.setSelection(s-1,0,"user"),i&&console.debug("Caret placed at the end of the document after blot:",e)):(i&&console.debug("Caret placed after character following blot at index:",o,e),t.setSelection(o+2,0,"user"),this.sendCaretBack(1,i))};onCreate=()=>{document.addEventListener("keyup",this.onKeyUp),this.formatter.quill.root.addEventListener("input",this.onKeyUp)};onDestroy=()=>{document.removeEventListener("keyup",this.onKeyUp),this.formatter.quill.root.removeEventListener("input",this.onKeyUp)};onKeyUp=t=>{const e=!!document.querySelector("[data-blot-formatter-modal]");if(!this.formatter.currentSpec||e)return;const i=this.formatter.currentSpec.getTargetBlot();i&&(t.code==="ArrowLeft"?(v.placeCaretBeforeBlot(this.formatter.quill,i,this.debug),this.formatter.hide()):t.code==="ArrowRight"&&(v.placeCaretAfterBlot(this.formatter.quill,i,this.debug),this.formatter.hide()))}}function Q(h){return h&&h.__esModule&&Object.prototype.hasOwnProperty.call(h,"default")?h.default:h}var E,L;function K(){if(L)return E;L=1;var h=function(c){return t(c)&&!e(c)};function t(a){return!!a&&typeof a=="object"}function e(a){var c=Object.prototype.toString.call(a);return c==="[object RegExp]"||c==="[object Date]"||s(a)}var i=typeof Symbol=="function"&&Symbol.for,o=i?Symbol.for("react.element"):60103;function s(a){return a.$$typeof===o}function n(a){return Array.isArray(a)?[]:{}}function r(a,c){return c.clone!==!1&&c.isMergeableObject(a)?x(n(a),a,c):a}function l(a,c,d){return a.concat(c).map(function(y){return r(y,d)})}function p(a,c){if(!c.customMerge)return x;var d=c.customMerge(a);return typeof d=="function"?d:x}function m(a){return Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(a).filter(function(c){return Object.propertyIsEnumerable.call(a,c)}):[]}function u(a){return Object.keys(a).concat(m(a))}function g(a,c){try{return c in a}catch{return!1}}function b(a,c){return g(a,c)&&!(Object.hasOwnProperty.call(a,c)&&Object.propertyIsEnumerable.call(a,c))}function V(a,c,d){var y={};return d.isMergeableObject(a)&&u(a).forEach(function(f){y[f]=r(a[f],d)}),u(c).forEach(function(f){b(a,f)||(g(a,f)&&d.isMergeableObject(c[f])?y[f]=p(f,d)(a[f],c[f],d):y[f]=r(c[f],d))}),y}function x(a,c,d){d=d||{},d.arrayMerge=d.arrayMerge||l,d.isMergeableObject=d.isMergeableObject||h,d.cloneUnlessOtherwiseSpecified=r;var y=Array.isArray(c),f=Array.isArray(a),Y=y===f;return Y?y?d.arrayMerge(a,c,d):V(a,c,d):r(c,d)}x.all=function(c,d){if(!Array.isArray(c))throw new Error("first argument should be an array");return c.reduce(function(y,f){return x(y,f,d)},{})};var X=x;return E=X,E}var Z=K();const G=Q(Z);class T{formatter;element;buttons={};constructor(t){this.formatter=t,this.element=document.createElement("div"),this.element.classList.add(this.formatter.options.toolbar.mainClassName),this.element.addEventListener("mousedown",e=>{e.stopPropagation()}),this.formatter.options.toolbar.mainStyle&&Object.assign(this.element.style,this.formatter.options.toolbar.mainStyle)}create=()=>{const t=[];this.formatter.actions.forEach(e=>{e.toolbarButtons.forEach(i=>{this.buttons[i.action]=i,t.push(i.create())})}),this.element.append(...t),this.formatter.overlay.append(this.element),this.formatter.options.debug&&console.debug("Toolbar created with buttons:",Object.keys(this.buttons),t)};destroy=()=>{this.element&&this.formatter.overlay.removeChild(this.element);for(const t of Object.values(this.buttons))t.destroy();this.buttons={},this.element.innerHTML="",this.formatter.options.debug&&console.debug("Toolbar destroyed")}}class k{constructor(t,e=!1){this.quill=t,this.debug=e;const i=t.container.querySelector(".ql-tooltip");console.debug("tooltip:",i),i?(k.watchTooltip(t,e),e&&console.debug("Tooltip watcher initialized for:",i)):console.warn("No tooltip found to watch for adjustments.")}quill;debug;static _repositionTooltip=(t,e,i=!1)=>{const o=t.getBoundingClientRect(),s=e.getBoundingClientRect();let n=o.left-s.left,r=o.top-s.top;const l=o.width,p=o.height,m=e.clientWidth,u=e.clientHeight;let g=!1;const b={};r<0&&(b.top=`${o.height}px`,g=!0),r+p>u&&(b.top=`${u-p}px`,g=!0),n<0&&(b.left="0px",g=!0),n+l>m&&(b.left=`${m-l}px`,g=!0),g?(i&&console.debug("Repositioning tooltip",b),b.top!==void 0&&(t.style.top=b.top),b.left!==void 0&&(t.style.left=b.left),t.classList.contains("ql-flip")&&t.classList.remove("ql-flip")):i&&console.debug("Tooltip position is fine, no changes needed")};static observers=new WeakMap;static watchTooltip(t,e=!1){const i=t.container.querySelector(".ql-tooltip"),o=t.container;if(!i){console.warn("No tooltip found to watch for adjustments.");return}this.removeTooltipWatcher(i,e);let s=!1;const n=new MutationObserver(r=>{if(!s){if(e)for(const l of r)console.debug("Tooltip mutation:",l.attributeName,i.getAttribute(l.attributeName));s=!0,this._repositionTooltip(i,o,e),setTimeout(()=>{s=!1},0)}});n.observe(i,{attributes:!0,attributeFilter:["style","class"]}),this.observers.set(i,n)}static removeTooltipWatcher(t,e=!1){let i=null;t instanceof HTMLDivElement?i=t:i=t.container.querySelector(".ql-tooltip"),i&&this.observers.has(i)&&(this.observers.get(i)?.disconnect(),this.observers.delete(i),e&&console.debug("Tooltip watcher removed for:",i))}destroy=()=>{this.quill.container.querySelector(".ql-tooltip")&&(k.removeTooltipWatcher(this.quill,this.debug),this.debug&&console.debug("Tooltip watcher removed on destroy"))}}const z=h=>{const t=h.import("formats/image"),e=["alt","height","width","title"];return class extends t{static blotName="image";static formats(o){return e.reduce((s,n)=>(o.hasAttribute(n)&&(s[n]=o.getAttribute(n)),s),{})}format(o,s){e.indexOf(o)>-1?s||o==="alt"?this.domNode.setAttribute(o,s):this.domNode.removeAttribute(o):super.format(o,s)}}},B=h=>{const t=h.import("parchment"),{ClassAttributor:e,Scope:i}=t;return class extends e{constructor(s=!1){super("iframeAlign","ql-iframe-align",{scope:i.BLOCK,whitelist:["left","center","right"]}),this.debug=s}debug;static attrName="iframeAlign";add(s,n){if(this.debug&&console.debug("IframeAlignAttributor.add",s,n),s instanceof HTMLElement){typeof n=="object"?(super.add(s,n.align),s.dataset.blotAlign=n.align):(super.add(s,n),s.dataset.blotAlign=n);let r=s.getAttribute("width");return r?(isNaN(Number(r.trim().slice(-1)))||(r=`${r}px`),s.style.setProperty("--resize-width",r),s.dataset.relativeSize=`${r.endsWith("%")}`):(s.style.removeProperty("--resize-width"),s.dataset.relativeSize="false"),this.debug&&console.debug("IframeAlignAttributor.add - node:",s,"aligned with:",n),!0}else return this.debug&&console.debug("IframeAlignAttributor.add - node is not an HTMLElement, skipping alignment"),!1}remove(s){this.debug&&console.debug("IframeAlignAttributor.remove",s),s instanceof HTMLElement&&(super.remove(s),delete s.dataset.blotAlign)}value(s){const n=super.value(s),r=s instanceof HTMLElement&&(s.style.getPropertyValue("--resize-width")||s.getAttribute("width"))||"",l={align:n,width:r,relativeSize:`${r.endsWith("%")}`};return this.debug&&console.debug("IframeAlignAttributor.value",s,l),l}}},R=h=>{const t=h.import("parchment"),{ClassAttributor:e,Scope:i}=t;return class extends e{constructor(s=!1){super("imageAlign","ql-image-align",{scope:i.INLINE,whitelist:["left","center","right"]}),this.debug=s}debug;static tagName="SPAN";static attrName="imageAlign";add(s,n){if(this.debug&&console.debug("ImageAlignAttributor.add",s,n),s instanceof HTMLSpanElement&&n){let r=s.querySelector("img");if(typeof n=="object"&&n.align)super.add(s,n.align),s.setAttribute("contenteditable","false"),n.title?s.setAttribute("data-title",n.title):s.removeAttribute("data-title"),n.align&&(r.dataset.blotAlign=n.align),this.debug&&console.debug("ImageAlignAttributor.add - imageElement:",r,"aligned with:",n.align);else if(typeof n=="string")super.add(s,n),r.dataset.blotAlign=n,this.debug&&console.debug("ImageAlignAttributor.add - imageElement:",r,"aligned with:",n);else return this.debug&&console.debug("ImageAlignAttributor.add - no value provided, skipping alignment"),!1;let l=this.getImageWidth(r);return s.setAttribute("data-relative-size",`${l?.endsWith("%")}`),!0}else{const r=s instanceof HTMLImageElement?s:s.querySelector("img");if(this.debug&&console.debug(`ImageAlignAttributor.add - ${s.tagName} is not a span, checking for image:`,r),r instanceof HTMLImageElement){const l=h.find(r);return this.debug&&console.debug("ImageAlignAttributor.add - found image blot:",l),l&&(s.firstChild instanceof HTMLSpanElement||!r.parentElement?.matches('span[class^="ql-image-align-"]'))&&(l.format("imageAlign",n),this.debug&&console.debug("ImageAlignAttributor.add - reapplying imageAlign format to image blot:",n,l)),!0}return!1}}remove(s){this.debug&&console.debug("ImageAlignAttributor.remove",s),s instanceof HTMLElement&&(super.remove(s),s.firstChild&&s.firstChild instanceof HTMLElement&&delete s.firstChild.dataset.blotAlign)}value(s){const n=s.querySelector("img");if(!n)return null;const r=n.parentElement,l=super.value(r),p=n.getAttribute("title")||"";let m=n.getAttribute("width")||"";parseFloat(m)||(n.complete?m=this.getImageWidth(n):n.onload=g=>{m=this.getImageWidth(g.target)});const u={align:l,title:p,width:m,contenteditable:"false",relativeSize:`${m.endsWith("%")}`};return this.debug&&console.debug("ImageAlignAttributor.value",s,u),u}getImageWidth(s){let n=s.getAttribute("width");return n?isNaN(Number(n.trim().slice(-1)))||(n=`${n}px`,s.setAttribute("width",n)):(n=`${s.naturalWidth}px`,s.setAttribute("width",n)),s.parentElement.style.setProperty("--resize-width",n),n}}},O=h=>{const t=h.import("formats/video");return class extends t{static blotName="video";static aspectRatio="16 / 9 auto";static create(i){const o=super.create(i);return o.setAttribute("width","100%"),o.style.aspectRatio=this.aspectRatio,o}html(){return this.domNode.outerHTML}}};class H{alignments={};options;formatter;debug;Scope;constructor(t){this.formatter=t,this.debug=t.options.debug??!1;const e=t.Quill.import("parchment");this.Scope=e.Scope,this.options=t.options,this.options.align.alignments.forEach(i=>{this.alignments[i]={name:i,apply:o=>{this.setAlignment(o,i)}}}),this.debug&&console.debug("DefaultAligner created with alignments:",this.alignments)}getAlignments=()=>Object.keys(this.alignments).map(t=>this.alignments[t]);clear=t=>{t!=null&&(t.domNode.tagName==="IMG"?t.parent!==null&&t.parent.domNode.tagName==="SPAN"&&(t.parent.format(this.formatter.ImageAlign.attrName,!1),this.debug&&console.debug("Cleared image alignment from parent span:",t.parent)):t.domNode.tagName==="IFRAME"&&(t.format(this.formatter.IframeAlign.attrName,!1),this.debug&&console.debug("Cleared iframe alignment:",t)))};isInlineBlot=t=>(t.statics?.scope&this.Scope.INLINE)===this.Scope.INLINE_BLOT;isBlockBlot=t=>(t.statics?.scope&this.Scope.BLOCK)===this.Scope.BLOCK_BLOT;hasInlineScope=t=>(t.statics.scope&this.Scope.INLINE)===this.Scope.INLINE;hasBlockScope=t=>(t.statics.scope&this.Scope.BLOCK)===this.Scope.BLOCK;isAligned=(t,e)=>{const i=this.getAlignment(t);return e?i===e.name:!!i};getAlignment=t=>t.domNode.dataset.blotAlign;setAlignment=(t,e)=>{if(t===null){this.debug&&console.debug("DefaultAligner.setAlignment called with null blot, no action taken");return}const i=this.isAligned(t,this.alignments[e]);if(this.debug&&console.debug("hasAlignment",i),this.clear(t),!i)if(this.isInlineBlot(t)||this.hasInlineScope(t)){if(this.debug&&console.debug("setting alignment",this.isInlineBlot(t)||this.hasInlineScope(t)),!t.domNode.getAttribute("width")&&this.options.resize.useRelativeSize&&!this.options.resize.allowResizeModeChange)try{const o=getComputedStyle(this.formatter.quill.root),s=this.formatter.quill.root.clientWidth-parseFloat(o.paddingLeft)-parseFloat(o.paddingRight);t.domNode.setAttribute("width",`${Math.min(Math.round(100*t.domNode.naturalWidth/s),100)}%`)}catch{this.debug&&console.debug("DefaultAligner.setAlignment Error setting image width:",t)}this.debug&&console.debug("DefaultAligner.setAlignment formatting image with",this.formatter.ImageAlign.attrName,{align:this.alignments[e].name,title:t.domNode.getAttribute("title")||""}),t.format(this.formatter.ImageAlign.attrName,{align:this.alignments[e].name,title:t.domNode.getAttribute("title")||""});try{const o=this.formatter.quill.getContents().ops;o.length===2&&o[1].insert===` `&&this.formatter.quill.insertText(this.formatter.quill.getLength(),` `,"user")}catch{}}else(this.isBlockBlot(t)||this.hasBlockScope(t))&&(this.debug&&console.debug("DefaultAligner.setAlignment formatting iframe with",this.formatter.IframeAlign.attrName,{align:this.alignments[e].name}),t.format(this.formatter.IframeAlign.attrName,this.alignments[e].name))}}class w{action;icon;onClick;options;element=null;initialVisibility=!0;constructor(t,e,i){this.action=t,this.icon=i.icons[t],this.onClick=e,this.options=i}create=()=>(this.element=document.createElement("span"),this.element.innerHTML=this.icon,this.element.className=this.options.buttonClassName,this.element.dataset.action=this.action,this.element.onclick=this.onClick,this.options.tooltips&&this.options.tooltips[this.action]&&(this.element.title=this.options.tooltips[this.action]),this.selected=this.preselect(),this.visible=this.initialVisibility,this._styleButton(),this.element);destroy=()=>{this.element&&(this.element.onclick=null,this.element.remove(),this.element=null)};preselect=()=>!1;get selected(){return this.element?.dataset.selected==="true"}set selected(t){this.element&&(this.element.dataset.selected=t.toString(),t?(this.element.classList.add(this.options.buttonSelectedClassName),this.options.buttonSelectedStyle&&Object.assign(this.element.style,this.options.buttonSelectedStyle)):(this.element.classList.remove(this.options.buttonSelectedClassName),this.options.buttonSelectedStyle&&(this.element.removeAttribute("style"),this.options.buttonStyle&&Object.assign(this.element.style,this.options.buttonStyle))))}get visible(){return this.element?.style.display!=="none"}set visible(t){this.element&&(typeof t=="boolean"&&(t=t?"inline-block":"none"),this.element.style.display=t)}_styleButton=()=>{if(this.element&&(this.options.buttonStyle&&Object.assign(this.element.style,this.options.buttonStyle),this.options.svgStyle)){const t=this.element.children[0];t&&Object.assign(t.style,this.options.svgStyle)}}}class N extends A{aligner;alignButtons={};constructor(t){super(t),this.aligner=new H(t),t.options.debug&&console.debug("AlignAction Aligner created:",this.aligner)}_createAlignmentButtons=()=>{for(const e of Object.values(this.aligner.alignments))this.alignButtons[e.name]=new w(e.name,this.onClickHandler,this.formatter.options.toolbar);const t=this.formatter.currentSpec?.getTargetBlot();if(t){const e=this.aligner.getAlignment(t);e&&this.alignButtons[e]&&(this.alignButtons[e].preselect=()=>!0),this.debug&&(console.debug("AlignAction alignment buttons created:",this.alignButtons),console.debug("Blot alignment on load:",e))}};_clearButtons=()=>{for(const t of Object.values(this.alignButtons))t.selected=!1;this.debug&&console.debug("AlignAction alignment buttons cleared")};onClickHandler=t=>{const e=t.target.closest(`span.${this.formatter.options.toolbar.buttonClassName}`);if(e){const i=e.dataset.action||"",o=this.formatter.currentSpec?.getTargetBlot();if(i&&o){const s=this.aligner.alignments[i];this._clearButtons(),this.aligner.isAligned(o,s)?(this.aligner.clear(o),this.debug&&console.debug("AlignAction clear alignment:",i,o)):(this.aligner.setAlignment(o,i),this.alignButtons[i].selected=!0,this.debug&&console.debug("AlignAction set alignment:",i,o))}}this.formatter.update()};onCreate=()=>{this._createAlignmentButtons(),this.toolbarButtons=Object.values(this.alignButtons),this.formatter.options.debug&&console.debug("AlignAction alignment buttons created:",this.toolbarButtons)};onDestroy=()=>{this.alignButtons={},this.toolbarButtons=[],this.formatter.options.debug&&console.debug("AlignAction alignment buttons destroyed")}}class q extends A{onCreate=()=>{document.addEventListener("keyup",this._onKeyUp),this.formatter.quill.root.addEventListener("input",this._onKeyUp)};onDestroy=()=>{document.removeEventListener("keyup",this._onKeyUp),this.formatter.quill.root.removeEventListener("input",this._onKeyUp)};_onKeyUp=t=>{const e=!!document.querySelector("[data-blot-formatter-modal]");if(!(!this.formatter.currentSpec||e)&&(t.code==="Delete"||t.code==="Backspace")){this.debug&&console.debug("DeleteAction keyup detected:",t.code);const i=this.formatter.currentSpec.getTargetElement();if(i){const o=this.formatter.Quill.find(i);if(o){const s=this.formatter.quill.getIndex(o);this.formatter.quill.deleteText(s,1,"user")}}this.formatter.hide()}}}class D extends A{_topLeftHandle;_topRightHandle;_bottomRightHandle;_bottomLeftHandle;_dragHandle=null;_dragStartX=0;_dragCursorStyle;_preDragWidth=0;_pinchStartDistance=0;_calculatedAspectRatio=0;_computedAspectRatio=void 0;_target;_editorStyle;_editorWidth=0;_useRelativeSize;_resizeModeButton=null;_isUnclickable=!1;_hasResized=!1;_formattedWidth="";_sizeInfoTimerId=null;_isImage=!1;_isSVG=!1;_naturalWidth=void 0;constructor(t){super(t),this._topLeftHandle=this._createHandle("top-left","nwse-resize"),this._topRightHandle=this._createHandle("top-right","nesw-resize"),this._bottomRightHandle=this._createHandle("bottom-right","nwse-resize"),this._bottomLeftHandle=this._createHandle("bottom-left","nesw-resize"),this._dragCursorStyle=document.createElement("style"),this._useRelativeSize=this.formatter.options.resize.useRelativeSize,t.options.resize.allowResizeModeChange&&(this._resizeModeButton=this._createResizeModeButton(),this.toolbarButtons=[this._resizeModeButton])}onCreate=()=>{this._target=this.formatter.currentSpec?.getTargetElement(),this._isUnclickable=this.formatter.currentSpec?.isUnclickable||!1,this._isImage=this._target instanceof HTMLImageElement,this._isImage&&(this._isSVG=this._isSvgImage()),this.formatter.overlay.append(this._topLeftHandle,this._topRightHandle,this._bottomRightHandle,this._bottomLeftHandle),this.formatter.overlay.addEventListener("mousedown",this._onOverlayMouseDown),this.formatter.overlay.addEventListener("mouseup",this._onOverlayMouseUp);const t={passive:!1};this.formatter.overlay.addEventListener("touchstart",this._onOverlayTouchStart,t),this.formatter.overlay.addEventListener("touchmove",this._onOverlayTouchMove,t),this.formatter.overlay.addEventListener("touchend",this._onOverlayTouchEnd,t);const e=this.formatter.options.resize.handleStyle||{};this._repositionHandles(e),this.debug&&console.debug("ResizeAction created with target:",this._target,"isUnclickable:",this._isUnclickable)};onDestroy=()=>{this._target=null,this._isUnclickable=!1,this._isImage=!1,this._naturalWidth=void 0,this._isSVG=!1,this._setCursor(""),[this._topLeftHandle,this._topRightHandle,this._bottomRightHandle,this._bottomLeftHandle].forEach(e=>{e.remove()}),this.formatter.overlay.removeEventListener("mousedown",this._onOverlayMouseDown),this.formatter.overlay.removeEventListener("mouseup",this._onOverlayMouseUp);const t={passive:!1};this.formatter.overlay.removeEventListener("touchstart",this._onOverlayTouchStart,t),this.formatter.overlay.removeEventListener("touchmove",this._onOverlayTouchMove,t),this.formatter.overlay.removeEventListener("touchend",this._onOverlayTouchEnd,t),this.formatter.update()};_createHandle=(t,e)=>{const i=document.createElement("div");return i.classList.add(this.formatter.options.resize.handleClassName),i.setAttribute("data-position",t),i.style.cursor=e,this.formatter.options.resize.handleStyle&&Object.assign(i.style,this.formatter.options.resize.handleStyle),i.addEventListener("pointerdown",this._onHandlePointerDown),i};_repositionHandles=t=>{const e=t?.width?`${-parseFloat(t.width)/2}px`:"0px",i=t?.height?`${-parseFloat(t.height)/2}px`:"0px",{style:o}=this._topLeftHandle;o.left=e,o.top=i;const{style:s}=this._topRightHandle;s.right=e,s.top=i;const{style:n}=this._bottomRightHandle;n.right=e,n.bottom=i;const{style:r}=this._bottomLeftHandle;r.left=e,r.bottom=i};_setCursor=t=>{if(!document.body){console.warn("ResizeAction: Cannot set cursor - document.body is null");return}try{t?(this._dragCursorStyle.innerHTML=`body, body * { cursor: ${t} !important; }`,document.head.contains(this._dragCursorStyle)||document.head.appendChild(this._dragCursorStyle)):document.head.contains(this._dragCursorStyle)&&document.head.removeChild(this._dragCursorStyle)}catch(e){console.error("ResizeAction: Error setting cursor style:",e)}};_resizeMode=t=>{if(t){if(this._hasResized=!1,this._formattedWidth="",this._target){this._useRelativeSize=this.formatter._useRelative(this._target),this._editorStyle=getComputedStyle(this.formatter.quill.root),this._editorWidth=this.formatter.quill.root.clientWidth-parseFloat(this._editorStyle.paddingLeft)-parseFloat(this._editorStyle.paddingRight);const e=this._target.getBoundingClientRect();if((e.height===void 0||e.height===0)&&(e.height=this._target.clientHeight+1),this._preDragWidth=e.width,this._computedAspectRatio=getComputedStyle(this._target).aspectRatio||"auto",this._calculatedAspectRatio=e.width/e.height,this._useRelativeSize)this._isUnclickable&&this._computedAspectRatio==="auto"&&(this._target.style.aspectRatio=this.formatter.options.video.defaultAspectRatio,console.warn(`No iframe aspect-ratio set. Set an aspect ratio either via custom blot or css. Using temporary aspect ratio "${this.formatter.options.video.defaultAspectRatio}"`));else if(this._isUnclickable&&this._computedAspectRatio!=="auto"){const i=this._computedAspectRatio.match(/(\d+)\s*\/\s*(\d+)/);if(i)try{this._calculatedAspectRatio=parseFloat(i[1])/parseFloat(i[2])}catch{}}this._isImage&&!this._useRelativeSize&&!this._isSVG&&this.formatter.options.resize.imageOversizeProtection&&(this._naturalWidth=this._target.naturalWidth),this._showSizeInfo(!0,e.width,e.height),this.debug&&console.debug("ResizeAction resize mode activated:",{target:this._target,useRelativeSize:this._useRelativeSize,editorWidth:this._editorWidth,preDragWidth:this._preDragWidth,aspectRatio:this._calculatedAspectRatio,computedAspectRatio:this._computedAspectRatio})}}else{if(this._target&&this._hasResized){let e=this._roundDimension(this._formattedWidth);this._target.setAttribute("width",e),this.formatter.toolbar.buttons.resizeMode&&(this.formatter.toolbar.buttons.resizeMode.selected=this.isRelative),this._isUnclickable?(this._target.style.setProperty("--resize-width",`${e}`),this._target.dataset.relativeSize=`${this.isRelative}`):this.isAligned&&this._target.parentElement&&(this._target.parentElement.style.setProperty("--resize-width",`${e}`),this._target.parentElement.dataset.relativeSize=`${this.isRelative}`),this.debug&&console.debug("ResizeAction resize mode deactivated:",{target:this._target,width:e,isRelative:this.isRelative,isAligned:this.isAligned})}this._naturalWidth=void 0,this.formatter.update(),this._showSizeInfo(!1)}};_onHandlePointerDown=t=>{this._resizeMode(!0),t.target instanceof HTMLElement&&this._target&&(this._dragHandle=t.target,this._setCursor(this._dragHandle.style.cursor),this._dragStartX=t.clientX,document.addEventListener("pointermove",this._onHandleDrag),document.addEventListener("pointerup",this._onHandlePointerUp))};_onHandleDrag=t=>{if(!this._target||!this._dragHandle)return;this._hasResized=!0;const e=t.clientX-this._dragStartX,i=this._dragHandle===this._topLeftHandle||this._dragHandle===this._bottomLeftHandle,o=Math.round(i?this._preDragWidth-e:this._preDragWidth+e),s=Math.max(Math.min(o,this._editorWidth),this.formatter.options.resize.minimumWidthPx);this._resizeTarget(s)};_onHandlePointerUp=()=>{this._setCursor(""),this._resizeMode(!1),document.removeEventListener("pointermove",this._onHandleDrag),document.removeEventListener("pointerup",this._onHandlePointerUp)};_onOverlayTouchStart=t=>{t.target===this.formatter.overlay&&(this._resizeMode(!0),this._target&&t.touches.length===2&&(t.preventDefault(),this._pinchStartDistance=this._calculateDistance(t.touches[0],t.touches[1]),this._preDragWidth=this._target.clientWidth))};_onOverlayTouchMove=t=>{if(t.target===this.formatter.overlay&&this._target&&t.touches.length===2&&this._pinchStartDistance!==null&&this._preDragWidth!==null&&(t.preventDefault(),this._target)){this._hasResized=!0;const i=this._calculateDistance(t.touches[0],t.touches[1])/this._pinchStartDistance;let o=Math.round(this._preDragWidth*i);o=Math.max(Math.min(o,this._editorWidth),10),this._resizeTarget(o)}};_onOverlayTouchEnd=t=>{t.target===this.formatter.overlay&&this._resizeMode(!1)};_onOverlayMouseDown=t=>{t.target===this.formatter.overlay&&this._resizeMode(!0)};_onOverlayMouseUp=t=>{t.target===this.formatter.overlay&&this._resizeMode(!1)};_resizeTarget=t=>{if(!this._target){console.warn("ResizeAction: Cannot resize - target element is null");return}try{t=Math.min(this._naturalWidth??1/0,t);const e=t/this._calculatedAspectRatio;this._updateSizeInfo(t,e),this.formatter._useRelative(this._target)?this._formattedWidth=`${100*t/this._editorWidth}%`:this._formattedWidth=`${t}px`,this._target.setAttribute("width",this._formattedWidth),this._target.setAttribute("height","auto"),this._isUnclickable?(!this._useRelativeSize&&this._computedAspectRatio==="auto"&&this._target.setAttribute("height",`${e|0}px`),this._target.style.setProperty("--resize-width",this._formattedWidth)):(this.isAligned&&this._target.parentElement&&this._target.parentElement.style.setProperty("--resize-width",this._formattedWidth),!this._useRelativeSize&&!this.formatter.options.image.autoHeight&&this._target.setAttribute("height",`${e|0}px`)),this.formatter.update()}catch(e){console.error("ResizeAction: Error resizing target element:",e)}};_showSizeInfo=(t,e=null,i=null)=>{t?(this._cancelSizeInfoTimer(),e!==null&&i!==null&&this._updateSizeInfo(e,i),this.formatter.sizeInfo.style.transition="",this.formatter.sizeInfo.style.opacity="1"):this._closeSizeInfo()};_updateSizeInfo=(t,e)=>{const i=Math.round(t),o=Math.round(e);let s=`${i} x ${o}px`;if(this.isRelative)s=`${Math.round(100*t/this._editorWidth)}% (${s})`;else if(!this._hasResized&&this._target){const n=this._target.getAttribute("width");if(n){const r=parseFloat(n);if(r!==t){const l=t/e,p=Math.round(r/l);s=`${n} x ${p}px (${s})`}}else if(this._target instanceof HTMLImageElement){const{naturalWidth:r,naturalHeight:l}=this._target;r!==t&&(s=`${r} x ${l}px (${s})`)}}this.formatter.sizeInfo.innerText=s};get isRelative(){return this._target?.getAttribute("width")?.endsWith("%")||!1}get isAligned(){return this._target?this._target.hasAttribute("data-blot-align"):!1}_createResizeModeButton=()=>{const t=new w("resizeMode",this._onResizeModeClickHandler,this.formatter.options.toolbar);return t.preselect=()=>this.isRelative,t};_onResizeModeClickHandler=t=>{t.stopImmediatePropagation(),this._swapResizeMode(!0)};_swapResizeMode=(t=!1)=>{if(this._target){const e=this._target.getBoundingClientRect();this._editorStyle=getComputedStyle(this.formatter.quill.root),this._editorWidth=this.formatter.quill.root.clientWidth-parseFloat(this._editorStyle.paddingLeft)-parseFloat(this._editorStyle.paddingRight);let i,o;this.isRelative?(i=`${Math.round(e.width)}px`,o=this.formatter.options.image.autoHeight?"auto":`${Math.round(e.height)}px`):(i=`${Math.round(100*e.width/this._editorWidth)}%`,o="auto"),this._target.setAttribute("width",`${i}`),this._target.setAttribute("height",`${o}`),this.formatter.currentSpec?.isUnclickable?(this._target.style.setProperty("--resize-width",`${i}`),this._target.dataset.relativeSize=`${this.isRelative}`):this.isAligned&&this._target.parentElement&&(this._target.parentElement.style.setProperty("--resize-width",`${i}`),this._target.parentElement.dataset.relativeSize=`${this.isRelative}`),this.formatter.toolbar.buttons.resizeMode.selected=this.isRelative,this.formatter.update(),t&&(this._showSizeInfo(!0,e.width,e.height),this._showSizeInfo(!1)),this.debug&&console.debug("ResizeAction resize mode swapped:",{target:this._target,newWidth:i,isRelative:this.isRelative,isAligned:this.isAligned})}};_closeSizeInfo=()=>{this._sizeInfoTimerId=setTimeout(()=>{this.formatter.sizeInfo.style.transition="opacity 1s",this.formatter.sizeInfo.style.opacity="0"},1e3)};_cancelSizeInfoTimer=()=>{this._sizeInfoTimerId!==null&&(clearTimeout(this._sizeInfoTimerId),this._sizeInfoTimerId=null)};_calculateDistance=(t,e)=>{const i=e.clientX-t.clientX,o=e.clientY-t.clientY;return Math.sqrt(i*i+o*o)};_roundDimension=t=>t.replace(/([^0-9.-]*)(-?[\d.]+)(.*)/,(e,i,o,s)=>`${i}${Math.round(Number(o))}${s}`);_isSvgImage=()=>this._target instanceof HTMLImageElement?this._target.src.startsWith("data:image/")?this._target.src.includes("image/svg+xml"):this._target.src.endsWith(".svg"):!1}class I{formatter;isUnclickable=!1;constructor(t){this.formatter=t}init=()=>{};getActions(){const t=[];return this.formatter.options.align.allowAligning&&t.push(new N(this.formatter)),this.formatter.options.resize.allowResizing&&t.push(new D(this.formatter)),this.formatter.options.delete.allowKeyboardDelete&&t.push(new q(this.formatter)),t.push(new v(this.formatter)),t}getTargetElement=()=>null;getTargetBlot=()=>{const t=this.getTargetElement();return t?this.formatter.Quill.find(t):null};getOverlayElement=()=>this.getTargetElement();setSelection=()=>{this.formatter.quill.setSelection(null)};onHide=()=>{}}const J="blot-formatter__proxy-image";class W extends I{selector;unclickable;proxyContainer;unclickableProxies;isUnclickable=!0;constructor(t){super(t),this.selector=t.options.video.selector,this.unclickable=null,this.proxyContainer=this._createProxyContainer(),this.unclickableProxies={}}init=()=>{this.formatter.quill.on("text-change",this._onTextChange),this.formatter.quill.root.addEventListener("scroll",()=>{this._repositionProxyImages()}),this._observeEditorResize()};_observeEditorResize=()=>{let t=null;new ResizeObserver(i=>{for(const o of i)t&&clearTimeout(t),t=window.setTimeout(()=>{this._repositionProxyImages()},200)}).observe(this.formatter.quill.root)};getTargetElement=()=>this.unclickable;getOverlayElement=()=>this.unclickable;_onTextChange=()=>{Object.entries(this.unclickableProxies).forEach(([t,{unclickable:e,proxyImage:i}])=>{try{this.formatter.quill.root.contains(e)||(i.remove(),delete this.unclickableProxies[t])}catch{}}),this.formatter.quill.root.querySelectorAll(`${this.selector}:not([data-blot-formatter-id])`).forEach(t=>{this._createUnclickableProxyImage(t)}),this._repositionProxyImages()};_createUnclickableProxyImage=t=>{const e=Array.from(crypto.getRandomValues(new Uint8Array(5)),r=>String.fromCharCode(97+r%26)).join("");t.dataset.blotFormatterId=e;const i=document.createElement("canvas"),o=i.getContext("2d");o&&(o.globalAlpha=0,o.fillRect(0,0,1,1));const s=document.createElement("img");s.src=i.toDataURL("image/png"),s.classList.add(J),s.dataset.blotFormatterId=e;const n={...this.formatter.options.video.proxyStyle,position:"absolute",margin:"0",userSelect:"none"};Object.assign(s.style,n),s.style.setProperty("-webkit-user-select","none"),s.style.setProperty("-moz-user-select","none"),s.style.setProperty("-ms-user-select","none"),this.formatter.options.debug&&s.style.setProperty("border","3px solid red"),this.proxyContainer.appendChild(s),s.addEventListener("click",this._onProxyImageClick),s.addEventListener("contextmenu",r=>{r.stopPropagation(),r.preventDefault()}),s.addEventListener("wheel",this.formatter._passWheelEventThrough),s.addEventListener("touchstart",this.formatter._onTouchScrollStart,{passive:!1}),s.addEventListener("touchmove",this.formatter._onTouchScrollMove,{passive:!1}),this.unclickableProxies[e]={unclickable:t,proxyImage:s},this.formatter.options.debug&&console.debug("UnclickableBlotSpec created proxy for unclickable:",t,"with ID:",e,"and proxy image:",s)};_repositionProxyImages=()=>{if(Object.keys(this.unclickableProxies).length>0){const t=this.formatter.quill.container.getBoundingClientRect(),e=this.formatter.quill.container.scrollLeft,i=this.formatter.quill.container.scrollTop;Object.entries(this.unclickableProxies).forEach(([o,{unclickable:s,proxyImage:n}])=>{try{const r=s.getBoundingClientRect();Object.assign(n.style,{left:`${r.left-t.left-1+e}px`,top:`${r.top-t.top+i}px`,width:`${r.width}px`,height:`${r.height}px`})}catch(r){const l=`Error positioning proxy image with id ${o}: `;console.error(l,`${r instanceof Error?r.message:r}`)}})}};_onProxyImageClick=t=>{const i=t.target.dataset.blotFormatterId;this.unclickable=this.unclickableProxies[`${i}`].unclickable,this.formatter.show(this)};_createProxyContainer=()=>{const t=document.createElement("div");return t.classList.add("proxy-container"),this.formatter.quill.container.appendChild(t),t}}class j extends W{constructor(t){super(t)}}class P extends A{modal;targetElement=null;currentBlot=null;constructor(t){super(t),this.toolbarButtons=[new w("attribute",this._onClickHandler,this.formatter.options.toolbar)],this.modal=this._createModal()}onCreate=()=>{this.targetElement=this.formatter.currentSpec?.getTargetElement(),this.currentBlot=this.formatter.currentSpec?.getTargetBlot()};onDestroy=()=>{this.targetElement=null,this.modal.form.removeEventListener("submit",this._onSubmitHandler),this.modal.form.removeEventListener("cancel",this._hideAltTitleModal),this.modal.element.removeEventListener("pointerdown",this._onPointerDownHandler),this.modal.cancelButton.removeEventListener("click",this._hideAltTitleModal),this.modal.element.remove()};_onClickHandler=()=>{this._showAltTitleModal()};_showAltTitleModal=()=>{this.targetElement&&(this.modal.altInput.value=this.targetElement.getAttribute("alt")||"",this.modal.titleInput.value=this.targetElement.getAttribute("title")||"",document.body.append(this.modal.element),this.formatter.options.debug&&console.debug("Showing Alt Title modal for:",this.targetElement))};_hideAltTitleModal=()=>{this.modal.element.remove()};_setAltTitle=()=>{if(this.targetElement){const t=typeof this.modal.altInput.value=="string"?this.modal.altInput.value:"",e=this.modal.titleInput.value;this.targetElement.setAttribute("alt",t),e?this.targetElement.setAttribute("title",e):this.targetElement.removeAttribute("title"),this.formatter.options.debug&&console.debug("Setting alt:",t,"title:",e,"on target element:",this.targetElement);const i=this.currentBlot?.parent?.formats()[this.formatter.ImageAlign.attrName]?.align;this.currentBlot&&i&&(this.formatter.options.debug&&console.debug("Updating title of image with alignment:",i),this.currentBlot.parent?.format(this.formatter.ImageAlign.attrName,!1),this.currentBlot.format(this.formatter.ImageAlign.attrName,{align:i,title:e}))}};_createModal=()=>{const t=Array.from(crypto.getRandomValues(new Uint8Array(5)),g=>String.fromCharCode(97+g%26)).join(""),e=document.createElement("div");e.id=`${t}-modal`,e.setAttribute("data-blot-formatter-modal","");const i=document.createElement("div"),o=document.createElement("form");o.id=`${t}-form`;const s=document.createElement("label");s.setAttribute("for","alt"),s.textContent=this.formatter.options.overlay.labels?.alt||this.formatter.options.image.altTitleModalOptions.labels.alt;const n=document.createElement("textarea");n.name="alt",n.rows=3;const r=document.createElement("label");r.setAttribute("for","title"),r.textContent=this.formatter.options.overlay.labels?.title||this.formatter.options.image.altTitleModalOptions.labels.title;const l=document.createElement("textarea");l.name="title",l.rows=3;const p=document.createElement("div"),m=document.createElement("button");m.type="submit",m.innerHTML=this.formatter.options.image.altTitleModalOptions.icons.submitButton,p.appendChild(m),o.appendChild(s),o.appendChild(n),o.appendChild(r),o.appendChild(l),o.appendChild(p);const u=document.createElement("button");return u.id=`${t}-cancel`,u.type="button",u.innerHTML=this.formatter.options.image.altTitleModalOptions.icons.cancelButton,this.formatter.options.image.altTitleModalOptions.styles&&(Object.assign(e.style,this.formatter.options.image.altTitleModalOptions.styles.modalBackground),Object.assign(i.style,this.formatter.options.image.altTitleModalOptions.styles.modalContainer),Object.assign(s.style,this.formatter.options.image.altTitleModalOptions.styles.label),Object.assign(n.style,this.formatter.options.image.altTitleModalOptions.styles.textarea),Object.assign(r.style,this.formatter.options.image.altTitleModalOptions.styles.label),Object.assign(l.style,this.formatter.options.image.altTitleModalOptions.styles.textarea),Object.assign(m.style,this.formatter.options.image.altTitleModalOptions.styles.submitButton),Object.assign(u.style,this.formatter.options.image.altTitleModalOptions.styles.cancelButton)),i.appendChild(o),i.appendChild(u),e.appendChild(i),o.addEventListener("submit",this._onSubmitHandler),o.addEventListener("cancel",this._hideAltTitleModal),e.addEventListener("pointerdown",this._onPointerDownHandler),u.addEventListener("click",this._hideAltTitleModal),{element:e,form:o,altInput:n,titleInput:l,cancelButton:u}};_onSubmitHandler=t=>{t.preventDefault(),this._setAltTitle(),this._hideAltTitleModal()};_onPointerDownHandler=t=>{t.target===this.modal.element&&this._hideAltTitleModal()}}class S extends A{options;modal;targetElement=null;imageDetails=null;static isEligibleForCompression=(t,e=!1)=>{let i=!1;if(t instanceof HTMLImageElement&&t.src.startsWith("data:image/")){const o=t.src.substring(5,t.src.indexOf(";"));i=o!=="svg+xml"&&o!=="gif"}return e&&console.debug("Image eligibility check:",{element:t,isEligible:i}),i};constructor(t){super(t),this.options=this.formatter.options.image.compressorOptions,this.toolbarButtons=[new w("compress",this._onClickHandler,this.formatter.options.toolbar)],this.modal=this._createModal()}onCreate=()=>{this.targetElement=this.formatter.currentSpec?.getTargetElement();const t=S.isEligibleForCompression(this.targetElement,this.debug);this.toolbarButtons[0].initialVisibility=t,this.debug&&console.debug("CompressAction initialized with target element:",this.targetElement,"is eligible:",t)};onDestroy=()=>{this.targetElement=null,this._hideModal(),this.modal.continueButton.removeEventListener("click",this._onContinueClick),this.modal.moreInfoButton.removeEventListener("click",this._onMoreInfoClick),this.modal.cancelButton.removeEventListener("click",this._hideModal),this.modal.element.removeEventListener("pointerdown",this._onBackgroundClick)};_onClickHandler=()=>{this._showModal()};_showModal=()=>{this.targetElement instanceof HTMLImageElement&&(this.imageDetails=this._getImageDetails(this.targetElement),this.imageDetails.canCompress?(this.modal.moreInfoButton.style.visibility="visible",this.modal.moreInfoText.style.display="none",document.body.append(this.modal.element)):this._displayFeedback(this.options.text.nothingToDo))};_hideModal=()=>{this.modal.element.remove()};_parseDimensions=t=>{let e=t.getAttribute("width"),i=t.getAttribute("height"),o=null,s=null;if(e)if(e.toLowerCase().endsWith("px"))o=parseFloat(e);else if(e.endsWith("%"))o=this.options.maxWidth??null;else if(e.toLowerCase().endsWith("em")||e.toLowerCase().endsWith("rem"))o=parseFloat(e)*16;else if(!isNaN(parseFloat(e)))o=parseFloat(e);else return[null,null];if(i)if(!isNaN(parseFloat(i)))s=parseFloat(i);else if(i.toLowerCase().endsWith("px"))s=parseFloat(i);else if(i.toLowerCase().endsWith("em")||i.toLowerCase().endsWith("rem"))s=parseFloat(i)*16;else if(o&&t.naturalWidth>0&&t.naturalHeight>0)s=o/(t.naturalWidth/t.naturalHeight);else return[null,null];return[o,s]};_getImageSize=t=>{const e=t.getAttribute("src");if(!e||!e.startsWith("data:image/"))return null;const i=e.split(",")[1];return i?Math.ceil(i.length*3/4):null};_displayFeedback=t=>{this.formatter.sizeInfo.innerHTML=t,this.formatter.sizeInfo.style.transition="",this.formatter.sizeInfo.style.opacity="1",setTimeout(()=>{this.formatter.sizeInfo.style.transition="opacity 1s",this.formatter.sizeInfo.style.opacity="0"},2500)};_getImageDetails=t=>{let[e,i]=this._parseDimensions(t);!e&&(this.options.maxWidth??1/0)<t.naturalWidth&&(e=this.options.maxWidth,i=e/(t.naturalWidth/t.naturalHeight));const o={naturalWidth:t.naturalWidth,naturalHeight:t.naturalHeight,targetWidth:e,targetHeight:i,size:this._getImageSize(t),canCompress:!!(e&&i&&e<t.naturalWidth&&S.isEligibleForCompression(t,this.debug))};return this.debug&&console.debug("Image details:",{element:t,...o}),o};_compressImage=t=>{if(this.imageDetails?.canCompress){const e=new Image;e.src=t.src,e.onload=()=>{this.debug&&console.debug("Compressing Image Copy loaded:",e);const i=document.createElement("canvas");i.width=this.imageDetails.targetWidth,i.height=this.imageDetails.targetHeight,i.getContext("2d").drawImage(e,0,0,i.width,i.height);const s=i.toDataURL("image/jpeg",this.options.jpegQuality),n=new TextEncoder().encode(t.src).length,r=new TextEncoder().encode(s).length;r<n&&(t.src=s);const l=`${Math.ceil((this.imageDetails.size-this._getImageSize(t))/1024)}kB`,p=`${this.options.text.reducedLabel}: ${l}<br> ${this.imageDetails.naturalWidth} x ${this.imageDetails.naturalHeight}px → ${i.width} x ${Math.round(i.height)}px `;return this.debug&&console.debug("Image compressed:",{"original size":n,"resized size":r,"size diff":l,"new dimensions":{width:i.width,height:Math.round(i.height)}}),this._displayFeedback(p),!0},e.onerror=i=>(console.error("Image loading failed:",i),this._displayFeedback(`Image loading failed: ${i}`),!1)}else this._displayFeedback(this.options.text.nothingToDo);return!0};_createModal=()=>{const t=document.createElement("div");t.setAttribute("data-blot-formatter-compress-modal","");const e=document.createElement("div"),i=document.createElement("div"),o=document.createElement("div"),s=document.createElement("div"),n=document.createElement("button"),r=document.createElement("button"),l=document.createElement("button");return o.style.display="none",s.append(n,r,l),e.append(i,o,s),t.appendChild(e),i.innerHTML=this.options.text.prompt,o.innerHTML=this.options.text.moreInfo||"",this.options.styles&&(Object.assign(t.style,this.options.styles.modalBackground),Object.assign(e.style,this.options.styles.modalContainer),Object.assign(s.style,this.options.styles.buttonContainer),Object.assign(n.style,{...this.options.styles.buttons,...this.options.buttons.cancel.style}),this.options.text.moreInfo?Object.assign(r.style,{...this.options.styles.buttons,...this.options.buttons.moreInfo.style}):r.style.visibility="hidden",Object.assign(l.style,{...this.options.styles.buttons,...this.options.buttons.continue.style})),n.innerHTML=this.options.icons.cancel,r.innerHTML=this.options.icons.moreInfo,l.innerHTML=this.options.icons.continue,l.addEventListener("click",this._onContinueClick),r.addEventListener("click",this._onMoreInfoClick),n.addEventListener("click",this._hideModal),t.addEventListener("pointerdown",this._onBackgroundClick),{element:t,moreInfoButton:r,cancelButton:n,continueButton:l,moreInfoText:o}};_onContinueClick=()=>{this.targetElement instanceof HTMLImageElement&&this._compressImage(this.targetElement),this._hideModal()};_onMoreInfoClick=()=>{this.modal.moreInfoText.innerHTML=this.options.text.moreInfo||"",this.modal.moreInfoText.style.display="block",this.modal.moreInfoButton.style.visibility="hidden"};_onBackgroundClick=t=>{t.stopImmediatePropagation(),t.target===this.modal.element&&(this.debug&&console.debug("Modal background clicked, hiding modal"),this._hideModal())}}class $ extends A{targetElement=null;currentBlot=null;toolbarButton;linkOptions;modal;constructor(t){super(t),this.linkOptions=this.formatter.options.image.linkOptions,this.toolbarButton=new w("link",this._onClickHandler,this.formatter.options.toolbar),this.toolbarButton.preselect=()=>!!this.getLink(),this.toolbarButtons=[this.toolbarButton],window.LinkAction=this}onCreate=()=>{this.targetElement=this.formatter.currentSpec?.getTargetElement(),this.currentBlot=this.formatter.currentSpec?.getTargetBlot()};onDestroy=()=>{this.targetElement=null,this._removeEventListeners(),this.hideLinkModal()};_addEventListeners=()=>{this.modal&&(this.modal.form.addEventListener("submit",this._formSubmitHandler),this.modal.cancelButton.addEventListener("click",this.hideLinkModal),this.modal.removeButton.addEventListener("click",this.removeLink),this.modal.background.addEventListener("click",this._onBackgroundClick),this.modal.input.addEventListener("contextmenu",this._trapContextEvent))};_removeEventListeners=()=>{this.modal&&(this.modal.form.removeEventListener("submit",this._formSubmitHandler),this.modal.cancelButton.removeEventListener("click",this.hideLinkModal),this.modal.removeButton.removeEventListener("click",this.removeLink),this.modal.background.removeEventListener("click",this._onBackgroundClick),this.modal.input.removeEventListener("contextmenu",this._trapContextEvent))};_trapContextEvent=t=>{t.stopImmediatePropagation()};_onClickHandler=()=>{this.showLinkModal()};_onBackgroundClick=t=>{t.target===this.modal?.background&&(t.stopImmediatePropagation(),t.preventDefault(),this.hideLinkModal(),this.debug&&console.debug("LinkAction modal background clicked, hiding modal"))};showLinkModal=()=>{if(this.targetElement){if(this.modal=this._buildModal(),!this.modal)return;this.formatter.overlay.append(this.modal.dialog,this.modal.background),this._addEventListeners(),this.modal.dialog.style.visibility="hidden",this.modal.dialog.show(),this._positionModal(this.modal.dialog),this.modal.dialog.style.visibility="visible",this.modal.input.focus(),this.modal.input.select()}};_buildModal=()=>{const t=document.createElement("dialog");t.className=this.linkOptions.modal.dialog.className,t.dataset.blotFormatterModal="",Object.assign(t.style,this.linkOptions.modal.dialog.style);const e=document.createElement("form");e.method="dialog",e.className=this.linkOptions.modal.form.className,Object.assign(e.style,this.linkOptions.modal.form.style);const i=document.createElement("label");i.htmlFor="link-url",i.textContent=this.linkOptions.modal.label.text,i.className=this.linkOptions.modal.label.className,Object.assign(i.style,this.linkOptions.modal.label.style);const o=document.createElement("input");o.type="url",o.id="link-url",o.name="url",o.value=this.getLink()||"",o.select(),o.autofocus=!0,o.className=this.linkOptions.modal.input.className,Object.assign(o.style,this.linkOptions.modal.input.style),o.placeholder=this.linkOptions.modal.input.placeholder||"";const s=document.createElement("button");s.type="submit",s.innerHTML=this.linkOptions.modal.buttons.submit.icon,s.className=this.linkOptions.modal.buttons.submit.className,Object.assign(s.style,this.linkOptions.modal.buttons.submit.style);const n=document.createElement("button");n.type="button",n.innerHTML=this.linkOptions.modal.buttons.cancel.icon,n.className=this.linkOptions.modal.buttons.cancel.className,Object.assign(n.style,this.linkOptions.modal.buttons.cancel.style);const r=document.createElement("button");r.type="button",r.innerHTML=this.linkOptions.modal.buttons.remove.icon,r.className=this.linkOptions.modal.buttons.remove.className,Object.assign(r.style,this.linkOptions.modal.buttons.remove.style),e.appendChild(i),e.appendChild(o),e.appendChild(s),e.appendChild(r),e.appendChild(n),t.appendChild(e);const l=document.createElement("div");return l.className=this.linkOptions.modal.background.className||"",Object.assign(l.style,this.linkOptions.modal.background.style),{dialog:t,background:l,form:e,label:i,input:o,okButton:s,cancelButton:n,removeButton:r}};_positionModal=t=>{const e=this.formatter.overlay.getBoundingClientRect(),i=this.formatter.quill.root.getBoundingClientRect(),o=t.offsetParent?.getBoundingClientRect()??{top:0,left:0},s=t.offsetWidth,n=t.offsetHeight;let r=e.left+e.width/2-s/2-o.left,l=e.top+e.height/2-n/2-o.top;const p=i.left-o.left,m=i.right-s-o.left;r=Math.min(Math.max(r,p),m);const u=i.top-o.top,g=i.bottom-n-o.top;l=Math.min(Math.max(l,u),g),t.style.position="absolute",t.style.left=`${r}px`,t.style.top=`${l}px`};hideLinkModal=()=>{this.modal?.dialog?.open&&this.modal.dialog.close(),this.modal?.dialog?.remove(),this.modal?.background&&this.modal.background.remove(),this._removeEventListeners(),this.modal=void 0};_formSubmitHandler=t=>{t.preventDefault();const e=t.target,o=new FormData(e).get("url").trim();this.debug&&console.debug("LinkAction form submitted with URL:",o),this.currentBlot&&(o?this.applyLink(o):this.removeLink())};getLink=()=>{const t=this.currentBlot;if(!t||!t.domNode)return null;const e=this.formatter.quill.getIndex(t),i=this.formatter.quill.getFormat(e,1,this.formatter.Quill.sources.SILENT);return this.debug&&console.debug("LinkAction getLink called, formats:",i),i.link||null};removeLink=()=>{const t=this.currentBlot;if(!t||!t.domNode)return;let e=t.parent;for(;e&&typeof e.formats=="function";){if(e.formats().link){e.format("link",null);break}e=e.parent}this.debug&&console.debug("LinkAction removeLink called, removed link from blot:",e),this.hideLinkModal(),this.toolbarButton.selected=!1};applyLink=t=>{t!==this.getLink()&&(this.removeLink(),this.currentBlot?.format("link",t),this.toolbarButton.s