diff --git a/packages/core/dist/TextIgniter.d.ts b/packages/core/dist/TextIgniter.d.ts index dbe42d1..08acfc0 100644 --- a/packages/core/dist/TextIgniter.d.ts +++ b/packages/core/dist/TextIgniter.d.ts @@ -12,6 +12,7 @@ import PopupToolbarView from './view/popupToolbarView'; import LinkPopupView from './view/linkPopupView'; import EventEmitter from './utils/events'; import { SpeechToTextHandler } from './handlers/speechToText'; +import EmojiPickerView from './view/emojiPickerView'; export interface CurrentAttributeDTO { bold: boolean; italic: boolean; @@ -46,6 +47,7 @@ declare class TextIgniter extends EventEmitter { } | null; debounceTimer: NodeJS.Timeout | null; undoRedoManager: UndoRedoManager; + emojiPickerView: EmojiPickerView; constructor(editorId: string, config: EditorConfig); getSelectionRange(): [number, number]; applyFontColor(color: string): void; diff --git a/packages/core/dist/assets/icons.d.ts b/packages/core/dist/assets/icons.d.ts index d3f3191..751bc53 100644 --- a/packages/core/dist/assets/icons.d.ts +++ b/packages/core/dist/assets/icons.d.ts @@ -18,4 +18,5 @@ export declare const icons: { image: string; stop_microphone: string; start_microphone: string; + emoji: string; }; diff --git a/packages/core/dist/assets/icons.ts b/packages/core/dist/assets/icons.ts index ff4971b..b5c2d8a 100644 --- a/packages/core/dist/assets/icons.ts +++ b/packages/core/dist/assets/icons.ts @@ -147,4 +147,13 @@ export const icons = { `, + + emoji: ` + Emoji + + + + + `, }; + diff --git a/packages/core/dist/index.d.ts b/packages/core/dist/index.d.ts index d657f5b..0b6abc7 100644 --- a/packages/core/dist/index.d.ts +++ b/packages/core/dist/index.d.ts @@ -263,7 +263,24 @@ declare class SpeechToTextHandler { toggleRecording(): void; private startRecording; private stopRecording; - private resetSilenceTimer; +} + +declare class EmojiPickerView { + private popup; + private gridArea; + private searchInput; + private onSelectCallback?; + private isOpen; + constructor(); + onSelect(cb: (char: string) => void): void; + open(element: HTMLElement): void; + close(): void; + getIsOpen(): boolean; + private buildPopup; + private getRecentEmojis; + private saveRecentEmoji; + private resolveChar; + private renderGrid; } interface CurrentAttributeDTO { @@ -300,6 +317,7 @@ declare class TextIgniter extends EventEmitter { } | null; debounceTimer: NodeJS.Timeout | null; undoRedoManager: UndoRedoManager; + emojiPickerView: EmojiPickerView; constructor(editorId: string, config: EditorConfig); getSelectionRange(): [number, number]; applyFontColor(color: string): void; diff --git a/packages/core/dist/index.js b/packages/core/dist/index.js index 979f7ab..8a3d8ca 100644 --- a/packages/core/dist/index.js +++ b/packages/core/dist/index.js @@ -1 +1 @@ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).TextIgniter={})}(this,function(t){"use strict";class e{constructor(){this.events={}}on(t,e){this.events[t]||(this.events[t]=[]),this.events[t].push(e)}emit(t,e){this.events[t]&&this.events[t].forEach(t=>t(e))}}class n{constructor(t,e={}){this.text=t;const n=document.getElementById("fontFamily"),i=document.getElementById("fontSize");let o="Arial",s="16px",l=document.getElementById("fontColorPicker"),r=document.getElementById("bgColorPicker");n&&(o=n.value),i&&(s=i.value);const a=e.fontColor||(l?l.value:"#000000"),d=e.bgColor||(r?r.value:"#ffffff");this.attributes={bold:e.bold||!1,italic:e.italic||!1,underline:e.underline||!1,strikethrough:e.strikethrough||!1,undo:e.undo||!1,redo:e.redo||!1,fontFamily:e.fontFamily||o,fontSize:e.fontSize||s,hyperlink:e.hyperlink||!1,fontColor:a,bgColor:d}}isBold(){return this.attributes.bold}setBold(t){this.attributes.bold=t}isItalic(){return this.attributes.italic}isUndo(){return this.attributes.undo}isRedo(){return this.attributes.redo}setItalic(t){this.attributes.italic=t}isUnderline(){return this.attributes.underline}setUnderline(t){this.attributes.underline=t}isStrikethrough(){return this.attributes.strikethrough||!1}setStrikethrough(t){this.attributes.strikethrough=t}setUndo(t){this.attributes.undo=t}setRedo(t){this.attributes.redo=t}clone(){return new n(this.text,Object.assign({},this.attributes))}hasSameAttributes(t){return this.attributes.bold===t.attributes.bold&&this.attributes.italic===t.attributes.italic&&this.attributes.underline===t.attributes.underline&&(this.attributes.strikethrough||!1)===(t.attributes.strikethrough||!1)&&this.attributes.undo===t.attributes.undo&&this.attributes.redo===t.attributes.redo&&this.attributes.fontFamily===t.attributes.fontFamily&&this.attributes.fontSize===t.attributes.fontSize&&this.attributes.italic===t.attributes.italic&&this.attributes.underline===t.attributes.underline&&this.attributes.hyperlink===t.attributes.hyperlink&&this.attributes.fontColor===t.attributes.fontColor&&this.attributes.bgColor===t.attributes.bgColor}getHyperlink(){return this.attributes.hyperlink||!1}setHyperlink(t){this.attributes.hyperlink=t}}class i extends e{get selectedBlockId(){return this._selectedBlockId}set selectedBlockId(t){if(this._selectedBlockId!==t){this._selectedBlockId=t;const e=this.getCursorOffset(document.querySelector('[id="editor"]')),n=this.getCursorOffset(document.querySelector('[data-id="'+t+'"]'));this.currentOffset=e-n}}constructor(){super(),this.dataIds=[],this.selectAll=!1,this._selectedBlockId=null,this.pieces=[new n("")],this.blocks=[{type:"text",dataId:"data-id-1734604240404",class:"paragraph-block",alignment:"left",pieces:[new n("​")]}],this.selectedBlockId="data-id-1734604240404",this.currentOffset=0}setEditorView(t){this.editorView=t}getPlainText(){return this.pieces.map(t=>t.text).join("")}setUndoRedoManager(t){this.undoRedoManager=t}insertAt(t,e,i,o="",s=0,l="",r="",a=!1){a||"batch"===r||this.undoRedoManager.saveUndoSnapshot(),console.log("inserted,",{start:i,text:t}),console.log("inserted,",this.blocks);let d=0,c=[],h=!1,u=0;""!==o&&null!==o&&(u=this.blocks.findIndex(t=>t.dataId===o),d=this.currentOffset);for(let o of this.blocks[u].pieces){const s=d+o.text.length;if(!h&&i<=s){const s=i-d;s>0&&c.push(new n(o.text.slice(0,s),Object.assign({},o.attributes))),c.push(new n(t,{bold:e.bold||!1,italic:e.italic||!1,underline:e.underline||!1,strikethrough:e.strikethrough||!1,hyperlink:e.hyperlink||!1})),st.dataId===i),-1===a)return;r=o}let c=-1;if(s&&t===r&&a>0&&e===t&&(c=a-1>=0&&"image"===this.blocks[a-1].type?a-2:a-1,c>=0&&this.blocks[c]))for(let t of this.blocks[c].pieces)l.push(t.clone()),d=!0;for(let i of this.blocks[a].pieces){const o=r+i.text.length,s=r;if(o<=t||s>=e)l.push(i.clone());else{const r=i.text;if(t>s){const e=r.slice(0,t-s);e.length>0&&l.push(new n(e,Object.assign({},i.attributes)))}if(e0&&l.push(new n(t,Object.assign({},i.attributes)))}}r=o}let h=this.mergePieces(l),u=!1;d&&c>=0?(!this.blocks[a]||"ol"!==this.blocks[a].listType&&"li"!==this.blocks[a].listType||(u=!0),this.blocks[c].pieces=h,this.blocks.splice(a,1)):0===h.length?this.blocks.length>1?(!this.blocks[a]||"ol"!==this.blocks[a].listType&&"li"!==this.blocks[a].listType||(u=!0),this.blocks.splice(a,1)):(h=[new n(" ")],this.blocks[a].pieces=h):this.blocks[a].pieces=h,u&&this.updateOrderedListNumbers(),this.emit("documentChanged",this)}deleteBlocks(){const t=this.blocks.some(t=>this.dataIds.includes(t.dataId)&&("ol"===t.listType||"li"===t.listType));this.blocks=this.blocks.filter(t=>{if(!this.dataIds.includes(t.dataId))return t}),this.dataIds=[],this.selectAll=!1,0===this.blocks.length&&this.blocks.push({dataId:`data-id-${Date.now()}`,class:"paragraph-block",type:"text",pieces:[new n("​")]}),t&&this.updateOrderedListNumbers(),this.emit("documentChanged",this)}getSelectedTextDataId(){const t=window.getSelection();if(!t||0===t.rangeCount)return null;const e=t.getRangeAt(0).startContainer,n=(e.nodeType===Node.TEXT_NODE?e.parentElement:e).closest("[data-id]");return(null==n?void 0:n.getAttribute("data-id"))||null}getAllSelectedDataIds(){var t;const e=window.getSelection();if(!e||0===e.rangeCount)return[];const n=e.getRangeAt(0),i=[],o=document.createNodeIterator(n.commonAncestorContainer,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT);let s;for(;s=o.nextNode();)if(n.intersectsNode(s)){const e=s.nodeType===Node.TEXT_NODE?s.parentElement:s,n=null===(t=null==e?void 0:e.closest("[data-id]"))||void 0===t?void 0:t.getAttribute("data-id");n&&!i.includes(n)&&i.push(n)}return this.removeExclusiveEndBlock(n,i),this.dataIds=i,console.log("selected id 3",this.dataIds,i),i}handleCtrlASelection(){const t=[],e=document.getElementById("editor");if(e){e.querySelectorAll("[data-id]").forEach(e=>{const n=e.getAttribute("data-id");n&&!t.includes(n)&&t.push(n)})}return this.dataIds=t,console.log("selected id 2",this.dataIds,t),t}getSelectedDataIds(){const t=window.getSelection();if(!t||0===t.rangeCount)return[];const e=t.getRangeAt(0),n=[],i=e.startContainer,o=e.endContainer,s=this.getDataIdFromNode(i),l=this.getDataIdFromNode(o);return s&&!n.includes(s)&&n.push(s),l&&!n.includes(l)&&n.push(l),this.removeExclusiveEndBlock(e,n),this.dataIds=n,console.log("selected id 1",this.dataIds,n),n}getDataIdFromNode(t){var e;const n=t.nodeType===Node.TEXT_NODE?t.parentElement:t;return(null===(e=null==n?void 0:n.closest("[data-id]"))||void 0===e?void 0:e.getAttribute("data-id"))||null}getCursorOffset(t){const e=window.getSelection();if(!e||0===e.rangeCount)return-1;const n=e.getRangeAt(0);let i=0;const o=t=>{if(t===n.startContainer)return i+=n.startOffset,!0;t.nodeType===Node.TEXT_NODE&&(i+=(t.textContent||"").length);for(const e of Array.from(t.childNodes))if(o(e))return!0;return!1};return o(t),i}formatAttribute(t,e,i,o){console.log("formatAttribute",t,e,i,o);let s=[],l=0,r=-1;if(""!==this.selectedBlockId&&null!==this.selectedBlockId){if(r=this.blocks.findIndex(t=>t.dataId===this.selectedBlockId),-1===r)return;l=this.currentOffset}for(let a of this.blocks[r].pieces){const r=l+a.text.length;if(r<=t||l>=e)s.push(a.clone());else{const r=l,d=a.text,c=Math.max(t-r,0),h=Math.min(e-r,d.length);c>0&&s.push(new n(d.slice(0,c),Object.assign({},a.attributes)));const u=new n(d.slice(c,h),Object.assign({},a.attributes));("bold"!==i&&"italic"!==i&&"underline"!==i&&"strikethrough"!==i&&"undo"!==i&&"redo"!==i&&"hyperlink"!==i||"boolean"!=typeof o)&&("fontFamily"!==i&&"fontSize"!==i&&"hyperlink"!==i&&"fontColor"!==i&&"bgColor"!==i||"string"!=typeof o)||(u.attributes[i]=o),s.push(u),he.dataId===t);if(-1===n)return;const i=this.blocks[n];"ol"===i.listType||"li"===i.listType?(i.listType=null,i.listStart=void 0,i.parentId=void 0):(i.listType="ol",i.listStart=1,i.parentId=i.dataId),this.updateOrderedListNumbers(),this.emit("documentChanged",this)}toggleOrderedListForMultipleBlocks(t){if(0===t.length)return;const e=t.sort((t,e)=>this.blocks.findIndex(e=>e.dataId===t)-this.blocks.findIndex(t=>t.dataId===e));if(e.every(t=>{const e=this.blocks.find(e=>e.dataId===t);return e&&("ol"===e.listType||"li"===e.listType)}))e.forEach(t=>{const e=this.blocks.find(e=>e.dataId===t);e&&(e.listType=null,e.listStart=void 0,e.parentId=void 0)});else{const t=e[0];e.forEach((e,n)=>{const i=this.blocks.find(t=>t.dataId===e);i&&(0===n?(i.listType="ol",i.listStart=1,i.parentId=t):(i.listType="li",i.listStart=n+1,i.parentId=t))})}this.updateOrderedListNumbers(),this.emit("documentChanged",this)}toggleUnorderedList(t){const e=this.blocks.findIndex(e=>e.dataId===t);if(-1===e)return;const n=this.blocks[e];n.listType="ul"===n.listType?null:"ul",this.emit("documentChanged",this)}updateOrderedListNumbers(){let t=1,e=null;for(let n=0;nt.focus(),0)}else this.editorView.container.focus();const i=window.getSelection();if(!i)return;const o=document.createRange();let s=0;const l=[this.editorView.container];let r;const a=(null===(n=this.editorView.container.textContent)||void 0===n?void 0:n.length)||0;if(!(t<0||t>a)){for(;r=l.pop();)if(3===r.nodeType){const e=r,n=s+e.length;if(t>=s&&t<=n){o.setStart(e,Math.min(t-s,e.length)),o.collapse(!0);break}s=n}else if("BR"===r.tagName){if(t===s){o.setStartBefore(r),o.collapse(!0);break}s++}else{const t=r;let e=t.childNodes.length;for(;e--;)l.push(t.childNodes[e])}i.removeAllRanges(),i.addRange(o)}}toggleBoldRange(t,e,n=""){const i=this.isRangeEntirelyAttribute(t,e,"bold");this.formatAttribute(t,e,"bold",!i)}toggleItalicRange(t,e,n=""){const i=this.isRangeEntirelyAttribute(t,e,"italic");this.formatAttribute(t,e,"italic",!i)}toggleUnderlineRange(t,e,n=""){const i=this.isRangeEntirelyAttribute(t,e,"underline");this.formatAttribute(t,e,"underline",!i)}toggleStrikethroughRange(t,e,n=""){const i=this.isRangeEntirelyAttribute(t,e,"strikethrough");this.formatAttribute(t,e,"strikethrough",!i)}toggleUndoRange(t,e,n=""){const i=this.isRangeEntirelyAttribute(t,e,"undo");this.formatAttribute(t,e,"undo",!i)}toggleRedoRange(t,e){const n=this.isRangeEntirelyAttribute(t,e,"redo");this.formatAttribute(t,e,"redo",!n)}applyFontColor(t,e,n,i=""){tt.dataId===this.selectedBlockId);if(-1===s)return!1;for(let l of this.blocks[s].pieces){const s=i+l.text.length;if(s>t&&it+e.text.length,0);if(i.dataId==e){let e=null;for(let o of i.pieces){const i=n,s=i+o.text.length;if(t>=i&&tt.dataId===e);n&&(n.alignment=t,this.emit("documentChanged",this))}getHtmlContent(t=!1){const e=document.getElementById("editor");if(!e)return void console.error("Editor container not found.");const n=e.innerHTML;return t&&navigator.clipboard.writeText(n).then(()=>{console.log("HTML copied to clipboard!")}).catch(t=>console.error("Failed to copy HTML:",t)),n}getCursorOffsetInParent(t){var e;console.log("textPosition -1:vicky",t);const n=document.querySelector(t);if(!n)return null;const i=window.getSelection();if(!i||0===i.rangeCount)return null;const o=i.getRangeAt(0);if(!n.contains(o.startContainer))return null;let s=0,l=null;const r=document.createTreeWalker(n,NodeFilter.SHOW_TEXT,null);let a=null;for(;r.nextNode();){const t=r.currentNode;if(console.log(t,"textPosition - currentNode: vicky"),t===o.startContainer){s+=o.startOffset,l=t,a=t.parentElement;break}s+=(null===(e=t.textContent)||void 0===e?void 0:e.length)||0}return console.log({offset:s,childNode:l,innerHTML:a.innerHTML,innerText:a.innerText},"textPosition - return values: vicky"),{offset:s,childNode:l,innerHTML:a.innerHTML,innerText:a.innerText}}removeExclusiveEndBlock(t,e){if(e.length<=1)return;const n=t.endContainer,i=t.endOffset;let o=!1;if((n.nodeType===Node.TEXT_NODE||n.nodeType===Node.ELEMENT_NODE)&&(o=0===i),!o)return;const s=this.getDataIdFromNode(n);if(!s)return;if(s!==this.getDataIdFromNode(t.startContainer)&&e.includes(s)){const t=e.lastIndexOf(s);t>-1&&e.splice(t,1)}}}function o(t){const e=window.getSelection();if(!e||0===e.rangeCount)return null;const n=e.getRangeAt(0),i=n.cloneRange();i.selectNodeContents(t),i.setEnd(n.startContainer,n.startOffset);const o=i.toString().length;i.setEnd(n.endContainer,n.endOffset);return{start:o,end:i.toString().length}}function s(t,e){if(!e)return;let n=0;const i=document.createRange();i.setStart(t,0),i.collapse(!0);const o=[t];let s,l=!1,r=!1;for(;!r&&(s=o.pop());)if(3===s.nodeType){const t=s,o=n+t.length;!l&&e.start>=n&&e.start<=o&&(i.setStart(t,e.start-n),l=!0),l&&e.end>=n&&e.end<=o&&(i.setEnd(t,e.end-n),r=!0),n=o}else if("BR"===s.tagName)l||e.start!==n||(i.setStartBefore(s),l=!0),l&&e.end===n&&(i.setEndBefore(s),r=!0),n++;else{const t=s;let e=t.childNodes.length;for(;e--;)o.push(t.childNodes[e])}const a=window.getSelection();a&&(a.removeAllRanges(),a.addRange(i))}function l(t){const e=o(t.container);return e?[e.start,e.end]:[0,0]}const r=/((https?:\/\/|www\.)[\w\-._~:\/?#[\]@!$&'()*+,;=%]+|\b[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(?:\/[\w\-._~:\/?#[\]@!$&'()*+,;=%]*)?)/g;function a(t,e){return e>0&&"@"===t[e-1]}function d(t){if(!t)return t;let e=t.trim();const n=e.match(/^https?:\/\/[\w.-]+(?::\d+)?\/(https?:\/\/.*)$/);return n&&(e=n[1]),/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(e)?e:e.startsWith("//")?"https:"+e:"https://"+e}class c{constructor(t,e){this.container=t,this.document=e}setImageHandler(t){this.imageHandler=t}render(){const t=o(this.container);this.container.innerHTML="",this.document.blocks.forEach(t=>{var e;if(""!==t.dataId){let n;if("image"===t.type){if(n=document.createElement("div"),n.setAttribute("data-id",t.dataId),n.setAttribute("class",t.class),n.setAttribute("type",t.type),n.style.textAlign=t.alignment||"left",t.image)if(this.imageHandler&&"function"==typeof this.imageHandler.createImageFragment)n.appendChild(this.imageHandler.createImageFragment(t.image,t.dataId));else{const e=document.createElement("img");e.src=t.image,n.appendChild(e)}}else if("ol"===t.listType||"li"===t.listType?(n=document.createElement("ol"),n.setAttribute("start",(null===(e=null==t?void 0:t.listStart)||void 0===e?void 0:e.toString())||"1")):n="ul"===t.listType?document.createElement("ul"):document.createElement("div"),n.setAttribute("data-id",t.dataId),n.setAttribute("class",t.class),n.setAttribute("type",t.type),n.style.textAlign=t.alignment||"left",Array.isArray(t.pieces))if("ol"===t.listType||"ul"===t.listType||"li"===t.listType){const e=document.createElement("li");t.pieces.forEach(t=>{e.appendChild(this.renderPiece(t))}),n.appendChild(e)}else t.pieces.forEach(t=>{n.appendChild(this.renderPiece(t))});this.container.appendChild(n)}}),s(this.container,t)}renderPiece(t){const e=t.text.split("\n");return this.wrapAttributes(e,t.attributes)}wrapAttributes(t,e){const n=document.createDocumentFragment();return t.forEach((i,o)=>{let s=document.createTextNode(i);if(e.strikethrough){const t=document.createElement("s");t.appendChild(s),s=t}if(e.underline){const t=document.createElement("u");t.appendChild(s),s=t}if(e.italic){const t=document.createElement("em");t.appendChild(s),s=t}if(e.bold){const t=document.createElement("strong");t.appendChild(s),s=t}const l=document.getElementById("fontFamily"),r=document.getElementById("fontSize");let a="Arial",c="16px";l&&(a=l.value),r&&(c=r.value);const h=document.createElement("span");if(h.style.fontFamily=e.fontFamily||a,h.style.fontSize=e.fontSize||c,e.fontColor&&"string"==typeof e.fontColor&&(h.style.color=e.fontColor),e.bgColor&&"string"==typeof e.bgColor&&(h.style.backgroundColor=e.bgColor),e.hyperlink&&"string"==typeof e.hyperlink){const t=document.createElement("a");t.href=d(e.hyperlink),t.appendChild(s),s=t}h.appendChild(s),s=h,n.appendChild(s),o{t.addEventListener("mousedown",t=>{t.preventDefault()})}),this.container.addEventListener("click",t=>{const e=t.target.closest("button");if(e){const t=e.getAttribute("data-action");t&&this.emit("toolbarAction",t)}})}updateActiveStates(t){if(this.container.querySelectorAll("button").forEach(e=>{const n=e.getAttribute("data-action");let i=!1;"bold"===n&&t.bold&&(i=!0),"italic"===n&&t.italic&&(i=!0),"underline"===n&&t.underline&&(i=!0),"strikethrough"===n&&t.strikethrough&&(i=!0),"hyperlink"===n&&t.hyperlink&&(i=!0),"undo"===n&&t.undo&&(i=!0),"redo"===n&&t.redo&&(i=!0),e.classList.toggle("active",i)}),this.container.querySelectorAll("select").forEach(e=>{const n=e.getAttribute("data-action");"fontFamily"===n&&t.fontFamily&&(e.value=t.fontFamily),"fontSize"===n&&t.fontSize&&(e.value=t.fontSize)}),t.fontColor){const e=document.getElementById("fontColorPicker");e&&(e.value=t.fontColor,e.dispatchEvent(new Event("input",{bubbles:!0})))}if(t.bgColor){const e=document.getElementById("bgColorPicker");e&&(e.value=t.bgColor,e.dispatchEvent(new Event("input",{bubbles:!0})))}}}const u={TOOLBAR_CLASSNAME:"toolbar",TOOLBAR_ID:"toolbar",EDITOR_CLASSNAME:"editor",EDITOR_ID:"editor",EDITOR_ELEMENT_NT_FOUND:"Editor element not found or incorrect element type.",FONT_FAMILY_SELECT_ID:"fontFamily",FONT_SIZE_SELECT_ID:"fontSize",FONT_COLOR_WRAPPER_ID:"fontColorWrapper",FONT_COLOR_ID:"fontColor",FONT_COLOR_PICKER_WRAPPER_ID:"colorWrapper",FONT_COLOR_PICKER_ID:"fontColorPicker",FONT_COLOR_RESET_ID:"colorResetFont",BG_COLOR_WRAPPER_ID:"bgColorWrapper",BG_COLOR_ID:"bgColor",BG_COLOR_PICKER_WRAPPER_ID:"colorBgWrapper",BG_COLOR_RESET_ID:"colorResetBG",BG_COLOR_PICKER_ID:"bgColorPicker",GET_HTML_BUTTON_ID:"getHtmlButton",LOAD_HTML_BUTTON_ID:"loadHtmlButton",HYPERLINK_CONTAINER_ID:"hyperlink-container",HYPERLINK_INPUT_ID:"hyperlink-input",HYPERLINK_PLACEHOLDER:"Enter a URL...",HYPERLINK_APPLY_BTN_ID:"apply-hyperlink",HYPERLINK_CANCEL_BTN_ID:"cancel-hyperlink",VIEW_HYPERLINK_CONTAINER_ID:"hyperlink-container-view",VIEW_HYPERLINK_LABEL_ID:"hyperlink-view-span",VIEW_HYPERLINK_ANCHOR_ID:"hyperlink-view-link",TEMPORARY_SELECTION_HIGHLIGHT_CLASS:"temporary-selection-highlight",PARAGRAPH_BLOCK_CLASS:"paragraph-block",IMAGE_CROSS_CLASS:"image-cross",TEST_HTML_CODE:'
ajsh diujaksdajsh diujaksdajsh
diujaksdasd 98hasiudasdh 98
This is a t this is a test work
This is a test work. this is a test work
da90 uasd y98asiodoiasda90 uasd y98asiodoiasda90 uasd y98asioda
sdjasdjasdja9sudoija9sudoija9sudoija90sdoa90sdoa90sdo
',TEST_BLOG_POST_HTML_CODE:'
Blog Post Title
Start writing your post here...
',TEST_NEWSLATER_HTML_CODE:'
Weekly Newsletter
Hello subscribers,
',TEST_RESUME_HTML_CODE:'
John Doe
Experience
• Role 1
',TEST_EMAIL_HTML_CODE:'
Subject: Important Update
Hi Team,
',TEST_MEETING_HTML_CODE:'
Meeting Minutes
Attendees:
Action Items:
',POPUP_TOOLBAR_CLASSNAME:"popup-toolbar",POPUP_TOOLBAR_ID:"popup-toolbar",TOAST_ID:"ti-toast",TOAST_SHOW_CLASS:"ti-toast--show",TOAST_DEFAULT_MESSAGE:"HTML copied to clipboard",TOAST_DEFAULT_DURATION_MS:2e3};class p{constructor(t,e,n){this.savedSelection=null,this.clickOutsideHandler=null,this.editorContainer=t,this.editorView=e,this.document=n}setUndoRedoManager(t){this.undoRedoManager=t}hanldeHyperlinkClick(t,e,n,i,o){const s=this.getCommonHyperlinkInRange(t,e,n,i,o);this.showHyperlinkInput(s)}getCommonHyperlinkInRange(t,e,n,i,o){let s=n,l=0;i&&(l=o.findIndex(t=>t.dataId===i));const r=o[l].pieces;let a=null;for(let n of r){const i=s+n.text.length;if(i>t&&s0){const t=c.getRangeAt(0);let o=null;if(t&&"function"==typeof t.getBoundingClientRect)o=t.getBoundingClientRect();else if(t&&"function"==typeof t.getClientRects){const n=null===(e=t.getClientRects)||void 0===e?void 0:e.call(t);o=n&&n.length?n[0]:null}(!o||Number.isNaN(o.top)&&Number.isNaN(o.left))&&(o=this.editorView.container.getBoundingClientRect());const l=(null===window||void 0===window?void 0:window.scrollY)||0,r=(null===window||void 0===window?void 0:window.scrollX)||0;s.style.top=`${(null!==(n=o.bottom)&&void 0!==n?n:o.top)+l+5}px`,s.style.left=`${(null!==(i=o.left)&&void 0!==i?i:0)+r}px`}l.value=t||"",this.savedSelection=o(this.editorView.container),this.highlightSelection(),l.focus(),r.onclick=null,a.onclick=null;const h=this.document.dataIds,u=()=>{const t=d(l.value.trim());t&&this.applyHyperlink(t,h),s.style.display="none"};r.onclick=u,l.onkeydown=t=>{"Enter"===t.key&&(t.preventDefault(),u())},a.onclick=()=>{this.removeHyperlink(h),s.style.display="none"}}}highlightSelection(){this.removeHighlightSelection();const t=window.getSelection();if(t&&t.rangeCount>0){const e=t.getRangeAt(0),n=document.createElement("span");n.className=u.TEMPORARY_SELECTION_HIGHLIGHT_CLASS,n.appendChild(e.extractContents()),e.insertNode(n),t.removeAllRanges();const i=document.createRange();i.selectNodeContents(n),t.addRange(i)}}removeHighlightSelection(){var t;const e=null===(t=this.editorContainer)||void 0===t?void 0:t.querySelectorAll(`span.${u.TEMPORARY_SELECTION_HIGHLIGHT_CLASS}`);null==e||e.forEach(t=>{const e=t.parentNode;if(e){for(;t.firstChild;)e.insertBefore(t.firstChild,t);e.removeChild(t)}})}applyHyperlink(t,e){this.undoRedoManager.saveUndoSnapshot(),this.removeHighlightSelection(),s(this.editorView.container,this.savedSelection);const[n,i]=l(this.editorView);if(n1?this.document.blocks.forEach(t=>{if(e.includes(t.dataId)){this.document.selectedBlockId=t.dataId;let e=0;t.pieces.forEach(t=>{e+=t.text.length});let i=n-e;this.document.formatAttribute(i,e,"hyperlink",o)}}):this.document.formatAttribute(n,i,"hyperlink",o),this.editorView.render();const s=window.getSelection();s&&s.removeAllRanges(),this.editorView.container.focus()}this.savedSelection=null}removeHyperlink(t){this.undoRedoManager.saveUndoSnapshot(),this.removeHighlightSelection(),s(this.editorView.container,this.savedSelection);const[e,n]=l(this.editorView);e1?this.document.blocks.forEach(n=>{if(t.includes(n.dataId)){this.document.selectedBlockId=n.dataId;let t=0;n.pieces.forEach(e=>{t+=e.text.length});let i=e-t;this.document.formatAttribute(i,t,"hyperlink",!1)}}):this.document.formatAttribute(e,n,"hyperlink",!1),this.editorView.render(),s(this.editorView.container,this.savedSelection),this.editorView.container.focus()),this.savedSelection=null}addClickOutsideListener(t){this.removeClickOutsideListener(),this.clickOutsideHandler=e=>{t&&!t.contains(e.target)&&this.hideHyperlinkViewButton()},setTimeout(()=>{document.addEventListener("click",this.clickOutsideHandler)},100)}removeClickOutsideListener(){this.clickOutsideHandler&&(document.removeEventListener("click",this.clickOutsideHandler),this.clickOutsideHandler=null)}showHyperlinkViewButton(t){var e,n,i;const o=document.getElementById(u.VIEW_HYPERLINK_CONTAINER_ID),s=document.getElementById(u.VIEW_HYPERLINK_ANCHOR_ID);if(o&&s){o.style.display="block";const l=window.getSelection();if(l&&l.rangeCount>0){const t=l.getRangeAt(0);let s=null;if(t&&"function"==typeof t.getBoundingClientRect)s=t.getBoundingClientRect();else if(t&&"function"==typeof t.getClientRects){const n=null===(e=t.getClientRects)||void 0===e?void 0:e.call(t);s=n&&n.length?n[0]:null}s||(s=this.editorView.container.getBoundingClientRect());const r=(null===window||void 0===window?void 0:window.scrollY)||0,a=(null===window||void 0===window?void 0:window.scrollX)||0;s&&(o.style.top=`${(null!==(n=s.bottom)&&void 0!==n?n:s.top)+r+5}px`,o.style.left=`${(null!==(i=s.left)&&void 0!==i?i:0)+a}px`)}t&&(s.innerText=t,s.href=d(t))}this.addClickOutsideListener(o)}hideHyperlinkViewButton(){const t=document.getElementById(u.VIEW_HYPERLINK_CONTAINER_ID);t&&(t.style.display="none"),this.removeClickOutsideListener()}}function g(t){return m((new DOMParser).parseFromString(t,"text/html").body,{bold:!1,italic:!1,underline:!1,hyperlink:!1})}function m(t,e){let i=Object.assign({},e);const o=[];if(t instanceof HTMLElement){if("A"===t.tagName){const e=t.getAttribute("href");e&&(i.hyperlink=e)}"STRONG"!==t.tagName&&"B"!==t.tagName||(i.bold=!0),"EM"!==t.tagName&&"I"!==t.tagName||(i.italic=!0),"U"===t.tagName&&(i.underline=!0),t.childNodes.forEach(t=>{o.push(...m(t,i))})}else if(t instanceof Text){const e=t.nodeValue||"";""!==e.trim()&&o.push(new n(e,Object.assign({},i)))}return o}const f={bold:'\n Bold\n \n ',italic:'\n Italic\n \n ',underline:'\n Underline\n \n ',strikethrough:'\n Strikethrough\n \n ',subscript:'\n Subscript\n \n ',superscript:'\n Superscript\n \n ',left_align:'\n Left Align\n \n ',center_align:'\n Center Align\n ',right_align:'\n Right Align',justify:'\n Justify\n ',bullet_list:'\n Bullet List',numbered_list:'\n Numbererd List\n \n ',insert_table:'\n Insert Table\n \n ',insert_layout:'\n Insert Layout\n \n ',heading:'\n Heading\n \n ',hyperlink:'\n Hyperlink\n \n \n ',image:'\n Insert Image\n \n ',stop_microphone:' \n \n \x3c!--!Font Awesome Free v7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--\x3e\n \n \n ',start_microphone:'\n \n \x3c!--!Font Awesome Free v7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--\x3e\n \n \n '},b={dropdowns:["fontFamily","fontSize"],colors:["fontColor","bgColor"],formatting:["bold","italic","underline","strikethrough"],alignment:["alignLeft","alignCenter","alignRight"],lists:["unorderedList","orderedList"],media:["hyperlink","image"],utility:["getHtmlContent","loadHtmlContent"]};function y(){const t=document.createElement("div");return t.className="toolbar-separator",t}function k(t,e){const n=u.EDITOR_ID,i=u.TOOLBAR_ID,o=u.POPUP_TOOLBAR_ID,s=["Arial","Times New Roman","Courier New","Verdana"],l=["12px","14px","16px","18px","20px"],r=document.getElementById(t);if(!r)throw new Error(u.EDITOR_ELEMENT_NT_FOUND);r.classList.add("editor-container");const a=document.createElement("div");a.className=u.TOOLBAR_CLASSNAME,a.id=i,r.appendChild(a),(null==e?void 0:e.showToolbar)||(a.style.display="none");const d=document.createElement("div");d.id=n,d.className=u.EDITOR_CLASSNAME,d.contentEditable="true",r.appendChild(d);const c={bold:"B",italic:"I",underline:"U",hyperlink:"🔗",alignLeft:"⇤",alignCenter:"↔",alignRight:"⇥",unorderedList:"•",orderedList:"1.",fontFamily:"fontFamily",fontSize:"fontSize",fontColor:"A",subscript:"X2",superscript:"X2",justify:"⇄",insert_table:"⊢",insert_layout:"❐",heading:"H",image:"📷",colors:"🎨"},h={bold:"Bold (Ctrl+B)",italic:"Italic (Ctrl+I)",underline:"Underline (Ctrl+U)",strikethrough:"Strikethrough",hyperlink:"Insert Link (Ctrl+H)",alignLeft:"Align Left (Ctrl+L)",alignCenter:"Align Center (Ctrl+E)",alignRight:"Align Right (Ctrl+R)",unorderedList:"Bullet List",orderedList:"Numbered List",fontColor:"Text Color",bgColor:"Highlight Color",image:"Insert Image",getHtmlContent:"Get HTML",loadHtmlContent:"Load HTML"},p=[{feature:"alignLeft",id:"alignLeft",icon:f.left_align},{feature:"alignCenter",id:"alignCenter",icon:f.center_align},{feature:"alignRight",id:"alignRight",icon:f.right_align},{feature:"unorderedList",id:"unorderedList",icon:f.bullet_list},{feature:"orderedList",id:"orderedList",icon:f.numbered_list},{feature:"hyperlink",id:"hyperlink",icon:f.hyperlink},{feature:"strikethrough",id:"strikethrough",icon:f.strikethrough}],g=(t,e)=>{const n=document.createElement("select");return n.dataset.action=t,n.id=t,e.forEach(t=>{const e=document.createElement("option");e.value=t,e.textContent=t,n.appendChild(e)}),n},m=document.createElement("div");m.id=o,m.className=u.POPUP_TOOLBAR_CLASSNAME,m.style.display="none",r.appendChild(m),e.popupFeatures&&e.popupFeatures.forEach((t,e)=>{e>0&&"hyperlink"===t&&m.appendChild(y());const n=p.find(e=>e.feature===t)||{icon:c[t]||t},i=document.createElement("button");i.dataset.action=t,i.innerHTML=n.icon,i.dataset.tooltip=h[t]||t.split("_").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" "),m.appendChild(i)});let k=null;e.features.forEach((t,n)=>{const i=function(t){for(const[e,n]of Object.entries(b))if(n.includes(t))return e;return null}(t);if(n>0&&i&&k&&i!==k&&a.appendChild(y()),k=i,"fontFamily"===t){const t=g(u.FONT_FAMILY_SELECT_ID,s);a.appendChild(t)}else if("fontSize"===t){const t=g(u.FONT_SIZE_SELECT_ID,l);a.appendChild(t)}else if("fontColor"===t){if(document.getElementById(u.FONT_COLOR_WRAPPER_ID))return;const t=document.createElement("span");t.id=u.FONT_COLOR_WRAPPER_ID,t.style.display="inline-flex",t.style.alignItems="center",t.style.position="relative",t.style.gap="4px";const e=document.createElement("button");e.id=u.FONT_COLOR_ID,e.type="button",e.dataset.tooltip=h.fontColor,e.innerHTML='A',t.appendChild(e);const n=document.createElement("div");n.id=u.FONT_COLOR_PICKER_WRAPPER_ID,n.style.display="none",n.style.position="absolute",n.style.top="100%",n.style.left="0",n.style.marginTop="4px",n.style.zIndex="1000",n.style.backgroundColor="#ffffff",n.style.border="1px solid #d1d1d1",n.style.borderRadius="4px",n.style.padding="8px",n.style.boxShadow="0 2px 8px rgba(0,0,0,0.15)",n.style.width="135px";const i=document.createElement("input");i.type="color",i.id=u.FONT_COLOR_PICKER_ID,i.setAttribute("data-action","fontColor"),i.style.width="100%",i.style.height="32px",i.style.border="1px solid #d1d1d1",i.style.borderRadius="4px",i.style.cursor="pointer",i.style.marginBottom="8px",i.value="#000000",n.appendChild(i);const o=document.createElement("button");o.id=u.FONT_COLOR_RESET_ID,o.type="button",o.textContent="Reset",o.style.display="block",o.style.width="100%",o.style.padding="6px 12px",o.style.fontSize="12px",o.style.border="1px solid #000000",o.style.borderRadius="4px",o.style.backgroundColor="#f8f8f8",o.style.cursor="pointer",o.style.transition="background-color 0.2s",o.onmouseenter=()=>o.style.backgroundColor="#e8e8e8",o.onmouseleave=()=>o.style.backgroundColor="#f8f8f8",n.appendChild(o),t.appendChild(n),a.appendChild(t)}else if("bgColor"===t){if(document.getElementById(u.BG_COLOR_WRAPPER_ID))return;const t=document.createElement("span");t.id=u.BG_COLOR_WRAPPER_ID,t.style.display="inline-flex",t.style.alignItems="center",t.style.position="relative",t.style.gap="4px";const e=document.createElement("button");e.id=u.BG_COLOR_ID,e.type="button",e.dataset.tooltip=h.bgColor,e.innerHTML='B',t.appendChild(e);const n=document.createElement("div");n.id=u.BG_COLOR_PICKER_WRAPPER_ID,n.style.display="none",n.style.position="absolute",n.style.top="100%",n.style.left="0",n.style.marginTop="4px",n.style.zIndex="1000",n.style.backgroundColor="#ffffff",n.style.border="1px solid #000000",n.style.borderRadius="4px",n.style.padding="8px",n.style.boxShadow="0 2px 8px rgba(0,0,0,0.15)",n.style.width="135px";const i=document.createElement("input");i.setAttribute("data-action","bgColor"),i.type="color",i.id=u.BG_COLOR_PICKER_ID,i.style.width="100%",i.style.height="32px",i.style.border="1px solid #000000ff",i.style.borderRadius="4px",i.style.cursor="pointer",i.style.marginBottom="8px",i.value="#ffffff",n.appendChild(i);const o=document.createElement("button");o.id=u.BG_COLOR_RESET_ID,o.type="button",o.textContent="Reset",o.style.display="block",o.style.width="100%",o.style.padding="6px 12px",o.style.fontSize="12px",o.style.border="1px solid #d1d1d1",o.style.borderRadius="4px",o.style.backgroundColor="#f8f8f8",o.style.cursor="pointer",o.style.transition="background-color 0.2s",o.onmouseenter=()=>o.style.backgroundColor="#e8e8e8",o.onmouseleave=()=>o.style.backgroundColor="#f8f8f8",n.appendChild(o),t.appendChild(n),a.appendChild(t)}else if("getHtmlContent"===t){const t=document.createElement("button");t.id=u.GET_HTML_BUTTON_ID,t.type="button",t.textContent="Get HTML",t.dataset.tooltip=h.getHtmlContent,a.appendChild(t)}else if("loadHtmlContent"===t){const t=document.createElement("select");t.id=u.LOAD_HTML_BUTTON_ID,t.dataset.action="loadHtmlContent",t.dataset.tooltip=h.loadHtmlContent,t.style.cursor="pointer",t.style.padding="4px 8px",t.style.border="1px solid #ccc",t.style.borderRadius="4px",t.style.backgroundColor="#f9f9f9",t.style.fontSize="13px",t.style.outline="none",t.style.color="#333",t.style.height="28px",t.addEventListener("mouseenter",()=>{t.style.backgroundColor="#eaeaea"}),t.addEventListener("mouseleave",()=>{t.style.backgroundColor="#f9f9f9"});const n=document.createElement("option");n.value="",n.textContent="Templates...",n.disabled=!0,n.selected=!0,t.appendChild(n);[...[{name:"Default Test",html:u.TEST_HTML_CODE},{name:"Blog Post",html:u.TEST_BLOG_POST_HTML_CODE},{name:"Newsletter",html:u.TEST_NEWSLATER_HTML_CODE},{name:"Resume",html:u.TEST_RESUME_HTML_CODE},{name:"Email",html:u.TEST_EMAIL_HTML_CODE},{name:"Meeting Notes",html:u.TEST_MEETING_HTML_CODE}],...e.templates||[]].forEach((e,n)=>{const i=document.createElement("option");i.value=n.toString(),i.dataset.html=e.html,i.textContent=e.name,t.appendChild(i)}),a.appendChild(t)}else if(p.map(t=>t.feature).includes(t)){const e=p.find(e=>e.feature===t),n=document.createElement("button");n.id=t,n.dataset.action=t,n.innerHTML=(null==e?void 0:e.icon)||"",n.dataset.tooltip=h[t]||t,a.appendChild(n)}else{const e=document.createElement("button");e.dataset.action=t,e.innerHTML=c[t]||t,e.id=t,e.dataset.tooltip=h[t]||t.split("_").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" "),a.appendChild(e)}});const C=document.createElement("div");C.id=u.HYPERLINK_CONTAINER_ID,C.style.display="none";const I=document.createElement("input");I.type="text",I.id=u.HYPERLINK_INPUT_ID,I.placeholder=u.HYPERLINK_PLACEHOLDER;const v=document.createElement("button");v.id=u.HYPERLINK_APPLY_BTN_ID,v.textContent="Link";const E=document.createElement("button");E.id=u.HYPERLINK_CANCEL_BTN_ID,E.textContent="Unlink",C.appendChild(I),C.appendChild(v),C.appendChild(E),a.appendChild(C);const w=document.createElement("div");w.id=u.VIEW_HYPERLINK_CONTAINER_ID,w.style.display="none";const x=document.createElement("span");x.id=u.VIEW_HYPERLINK_LABEL_ID,x.innerHTML="Visit URL : ";const T=document.createElement("a");return T.id=u.VIEW_HYPERLINK_ANCHOR_ID,T.href="",T.target="_blank",w.appendChild(x),w.appendChild(T),a.appendChild(w),{mainEditorId:n,toolbarId:i,popupToolbarId:o}}class C{constructor(t){this.htmlString=t,this.doc=(new DOMParser).parseFromString(t,"text/html")}parse(){const t=this.doc.body.children;let e=[];return Array.from(t).forEach((t,n)=>{const i=this.parseElement(t);console.log(t,"element parse",n,i),e.push(i)}),console.log(e,"element--jsondata"),e}parseElement(t){const e=t.getAttribute("data-id")||`data-id-${Date.now()}-${Math.floor(1e3*Math.random())}`,n=t.className||"paragraph-block",i=t.style.textAlign||"left";let o=null,s=null;"UL"===t.tagName?o="ul":"OL"===t.tagName&&(o="ol",s=parseInt(t.getAttribute("start")||"1",10));let l=[];return o?this.parseListItems(t,l):this.parseParagraphText(t,l),Object.assign(Object.assign(Object.assign({dataId:e,class:n,alignment:i,pieces:l},o?{listType:o}:{}),null!==s?{listStart:s}:{}),{})}parseListItems(t,e){t.querySelectorAll("li").forEach(t=>{const i=this.extractTextAttributes(t);i&&e.push(new n(i.text,i.attributes))})}parseParagraphText(t,e){const i=t.querySelectorAll("span"),o=new Map;i.forEach(t=>{const e=this.extractTextAttributes(t);if(console.log(e,"piece parseParagraphText span",t.textContent,t.style.color),e){const t=o.get(e.text);t?(t.attributes.bold=t.attributes.bold||e.attributes.bold,t.attributes.italic=t.attributes.italic||e.attributes.italic,t.attributes.underline=t.attributes.underline||e.attributes.underline,t.attributes.fontFamily=e.attributes.fontFamily||t.attributes.fontFamily,t.attributes.fontSize=e.attributes.fontSize||t.attributes.fontSize,t.attributes.fontColor=e.attributes.fontColor||t.attributes.fontColor,t.attributes.bgColor=e.attributes.bgColor||t.attributes.bgColor):o.set(e.text,Object.assign({},e))}}),o.forEach(t=>{e.push(new n(t.text,t.attributes))}),console.log(e,"pieces--parseParagraphText (merged)")}extractTextAttributes(t){var e;const n=t.textContent||"";return n?(console.log("extractTextAttributes node",t,t.style.color),{text:n,attributes:{bold:null!==t.querySelector("b, strong"),italic:null!==t.querySelector("i, em"),underline:null!==t.querySelector("u"),undo:!1,redo:!1,fontFamily:t.style.fontFamily||"Arial",fontSize:t.style.fontSize||"12px",hyperlink:!!t.querySelector("a")&&(null===(e=t.querySelector("a"))||void 0===e?void 0:e.getAttribute("href")),fontColor:t.style.color,bgColor:t.style.backgroundColor}}):null}rgbToHex(t,e=!1){const n=t.match(/\d+/g);if(!n||n.length<3)return null;const i=n.map(t=>{const e=parseInt(t);return e<0||e>255?"00":e.toString(16).padStart(2,"0")}).join("");return e||"000000"!==i?`#${i}`:null}}class I{constructor(t,e){this.editor=t,this.document=e,this.isImageHighlighted=!1,this.highLightedImageDataId="",this.currentCursorLocation=0,this.isCrossIconVisible=!1}setEditorView(t){this.editorView=t}insertImage(){const t=document.createElement("input");t.type="file",t.accept="image/*",t.click(),t.onchange=()=>{const e=t.files?t.files[0]:null;if(e){const t=new FileReader;t.onload=t=>{var e;const n=null===(e=t.target)||void 0===e?void 0:e.result;this.insertImageAtCursor(n)},t.readAsDataURL(e)}}}insertImageAtCursor(t){if(!t)return;const[e,n]=l(this.editorView);n>e&&this.document.deleteRange(e,n,this.document.selectedBlockId),this.insertImageAtPosition(t,e,this.document.selectedBlockId)}setCursorPostion(t,e){if("number"!=typeof t||!e)return;const n=document.querySelector(`[data-id="${e}"]`);n&&("function"==typeof n.focus&&n.focus(),setTimeout(()=>{const e=document.createRange(),i=window.getSelection();if(n.firstChild)e.setStart(n.firstChild,t);else{const t=document.createTextNode("");n.appendChild(t),e.setStart(t,0)}e.collapse(!0),null==i||i.removeAllRanges(),null==i||i.addRange(e)},0))}insertImageAtPosition(t,e,i){if(!t||"number"!=typeof e||!this.editorView)return;console.log(t,e,i,"vicky insertImageAtPosition",this.document.blocks);const o=`data-id-${Date.now()}-${1e3*Math.random()}`,s=`data-id-${Date.now()}-${1e3*Math.random()}`,l=`data-id-${Date.now()}-${1e3*Math.random()}`,r={dataId:o,class:u.PARAGRAPH_BLOCK_CLASS,pieces:[new n(" ")],type:"image",image:t},a={dataId:s,class:u.PARAGRAPH_BLOCK_CLASS,pieces:[new n(" ")],type:"text"};let d=this.document.selectedBlockId;const c=this.document.blocks.findIndex(t=>t.dataId===this.document.selectedBlockId);let h=[];const{remainingText:p,piece:g}=function(t,e){const n=window.getSelection();if(!n||0===n.rangeCount)return{remainingText:"",piece:null};const i=n.getRangeAt(0).startContainer;let o="";const s=e.blocks.filter(e=>{if(e.dataId===t)return e});if(!s[0]||!s[0].pieces)return{remainingText:"",piece:null};const l=document.querySelector(`[data-id="${t}"]`),r=e.getCursorOffsetInParent(`[data-id="${t}"]`);let a=[],d=0;if(s[0].pieces.forEach((t,e)=>{o+=t.text,(null==r?void 0:r.innerText)===t.text&&(d=e,a.push(t))}),s[0].pieces.length>1&&s[0].pieces.forEach((t,e)=>{d0){const t=p.split(" ");let e=[];""!==t[0]||void 0!==t[1]?1===g.length?e=[new n(m,g[0].attributes)]:(e.push(new n(" "+t[0]+" ",g[0].attributes)),g.length>=2&&g.forEach((t,n)=>{0!==n&&e.push(t)})):e=[new n(" ")],console.log(this.document.selectedBlockId,"uniqueId3 extractTextFromDataId-vicky",l),f=function(t,e,n){const i=t.findIndex(t=>t.dataId===e);return-1===i?(console.error(`Block with dataId "${e}" not found.`),t):[...t.slice(0,i+1),n,...t.slice(i+1)]}(this.document.blocks,this.document.selectedBlockId||"",{dataId:l,class:u.PARAGRAPH_BLOCK_CLASS,pieces:e,type:"text"})}this.document.blocks=f,this.document.deleteRange(this.currentCursorLocation,this.currentCursorLocation+p.length,this.document.selectedBlockId,this.document.currentOffset),this.document.blocks.length>c+1?this.document.blocks.forEach((t,e)=>{h.push(t),e===c?h.push(r):d===this.document.selectedBlockId&&(d=t.dataId)}):(h=[...this.document.blocks,r,a],d=a.dataId),this.document.blocks=h,this.editorView.render(),this.document.selectedBlockId=d;const b=document.querySelector(`[data-id="${d}"]`);b.focus(),setTimeout(()=>{const t=document.createRange(),e=window.getSelection();if(b.firstChild)t.setStart(b.firstChild,1);else{const e=document.createTextNode("");b.appendChild(e),t.setStart(e,0)}t.collapse(!0),null==e||e.removeAllRanges(),null==e||e.addRange(t)},0)}createImageFragment(t,e){if(!t||!e)return document.createDocumentFragment();const n=document.createDocumentFragment(),i=document.createElement("img");i.src=t,i.style.maxWidth="30%",i.setAttribute("contenteditable","false"),n.appendChild(i);const o=document.createElement("span");return o.setAttribute("contenteditable","false"),o.appendChild(n),i.addEventListener("click",()=>this.addStyleToImage(e)),o}addStyleToImage(t){if(t&&!this.isCrossIconVisible){const e=document.querySelector(`[data-id="${t}"]`),n=null==e?void 0:e.querySelector("span");n&&(n.style.position="relative");const i=null==e?void 0:e.querySelector("img");i&&(i.style.border="2px solid blue");const o=document.createElement("div");o.className=u.IMAGE_CROSS_CLASS,o.innerHTML="x",Object.assign(o.style,{position:"absolute",top:"0",left:"50%",transform:"translate(-50%, 0)",background:"#fff",borderRadius:"50%",width:"30px",height:"30px",display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer",border:"3px solid blue",zIndex:"999"}),o.addEventListener("mouseover",()=>o.style.border="3px solid black"),o.addEventListener("mouseout",()=>o.style.border="3px solid blue"),o.addEventListener("click",t=>{t.stopPropagation(),this.deleteImage()}),null==n||n.appendChild(o),this.isImageHighlighted=!0,this.highLightedImageDataId=t,this.isCrossIconVisible=!0}}clearImageStyling(){if(!this.highLightedImageDataId)return;const t=document.querySelector(`[data-id="${this.highLightedImageDataId}"]`);if(t){const e=t.querySelector("span");null==e||e.removeAttribute("style");const n=null==e?void 0:e.querySelector("img");n&&n.removeAttribute("style");const i=null==e?void 0:e.querySelector(`.${u.IMAGE_CROSS_CLASS}`);null==i||i.remove(),this.highLightedImageDataId=""}this.isCrossIconVisible=!1}deleteImage(){this.highLightedImageDataId&&(this.document.blocks=this.document.blocks.filter(t=>t.dataId!==this.highLightedImageDataId),this.highLightedImageDataId="",this.isImageHighlighted=!1,this.clearImageStyling(),this.document.emit("documentChanged",this))}}class v{constructor(t,e){this.snapshotUndoStack=[],this.snapshotRedoStack=[],this.maxSnapshots=5e3,this.document=t,this.editorView=e}createSnapshot(){const[t,e]=l(this.editorView);return{blocks:JSON.parse(JSON.stringify(this.document.blocks)),dataIds:[...this.document.dataIds],selectedBlockId:this.document.selectedBlockId,currentOffset:this.document.currentOffset,selection:this.getCurrentSelection(),cursorPosition:t}}getCurrentSelection(){const t=o(this.document.editorView.container);return t?{start:t.start,end:t.end}:{start:0,end:0}}saveUndoSnapshot(){const t=this.createSnapshot();console.log("Saving snapshot:",t.cursorPosition,"Stack length:",this.snapshotUndoStack.length),this.snapshotUndoStack.push(t),this.snapshotUndoStack.length>this.maxSnapshots&&this.snapshotUndoStack.shift(),this.snapshotRedoStack=[]}restoreSnapshot(t){this.document.blocks=t.blocks,this.document.dataIds=t.dataIds,this.document._selectedBlockId=t.selectedBlockId,this.document.currentOffset=t.currentOffset;for(let t of this.document.blocks)t.pieces&&Array.isArray(t.pieces)&&(t.pieces=t.pieces.map(t=>new n(t.text,t.attributes)));this.document.emit("documentChanged",this.document),setTimeout(()=>{this.document.setCursorPosition(t.cursorPosition||0)},0)}undo(){if(console.log("UNDO - Undo stack length:",this.snapshotUndoStack.length),console.log("UNDO - Redo stack length:",this.snapshotRedoStack.length),0===this.snapshotUndoStack.length)return;const t=this.createSnapshot();this.snapshotRedoStack.push(t),this.snapshotRedoStack.length>this.maxSnapshots&&this.snapshotRedoStack.shift();const e=this.snapshotUndoStack.pop();e&&(console.log("UNDO - Restoring cursor position:",e.cursorPosition),this.restoreSnapshot(e))}redo(){if(0===this.snapshotRedoStack.length)return;const t=this.createSnapshot();this.snapshotUndoStack.push(t),this.snapshotUndoStack.length>this.maxSnapshots&&this.snapshotUndoStack.shift();const e=this.snapshotRedoStack.pop();e&&this.restoreSnapshot(e)}}class E extends e{constructor(t){super(),this.container=t,this.setupButtons()}setupButtons(){this.container.addEventListener("mousedown",t=>{t.preventDefault()}),this.container.addEventListener("click",t=>{const e=t.target.closest("button");if(e){const t=e.getAttribute("data-action");t&&this.emit("popupAction",t)}})}show(t){const e=t.getRangeAt(0).getBoundingClientRect();if(0===e.width&&0===e.height)return void this.hide();this.container.style.display="flex";const n=this.container.offsetWidth,i=this.container.offsetHeight;let o=e.top+window.scrollY-i-8,s=e.left+window.scrollX+e.width/2-n/2;o{const n=e.getAttribute("data-action");let i=!1;"bold"===n&&t.bold&&(i=!0),"italic"===n&&t.italic&&(i=!0),"underline"===n&&t.underline&&(i=!0),"strikethrough"===n&&t.strikethrough&&(i=!0),"hyperlink"===n&&t.hyperlink&&(i=!0),e.classList.toggle("active",i)})}}class w{constructor(){this.linkElement=null,this.createPopup()}setCallbacks(t,e){this.onOpenClick=t,this.onUnlinkClick=e}createPopup(){this.popup=document.createElement("div"),this.popup.className="link-popup",this.popup.style.cssText="\n position: absolute;\n background: #000;\n border-radius: 4px;\n padding: 2px;\n box-shadow: 0 1px 4px rgba(0,0,0,0.5);\n z-index: 1000;\n display: none;\n ";const t=this.createButton("Open","🔗"),e=this.createButton("Unlink","✕");t.addEventListener("click",()=>this.handleOpenClick()),e.addEventListener("click",()=>this.handleUnlinkClick()),this.popup.appendChild(t),this.popup.appendChild(e),document.body.appendChild(this.popup)}createButton(t,e){const n=document.createElement("button");return n.innerHTML=`${e}`,n.title=t,n.style.cssText="\n background: transparent;\n color: white;\n border: none;\n padding: 4px;\n margin: 0 1px;\n border-radius: 2px;\n cursor: pointer;\n font-size: 16px;\n transition: background 0.1s;\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n ",n.addEventListener("mouseenter",()=>{n.style.background="#333"}),n.addEventListener("mouseleave",()=>{n.style.background="transparent"}),n}handleOpenClick(){this.linkElement&&this.onOpenClick&&this.onOpenClick(this.linkElement.href)}handleUnlinkClick(){this.onUnlinkClick&&this.linkElement&&this.onUnlinkClick(this.linkElement)}show(t,e,n){this.linkElement=t;const i=t.getBoundingClientRect();this.popup.style.left=`${i.left+window.scrollX}px`,this.popup.style.top=`${i.bottom+window.scrollY+5}px`,this.popup.style.display="flex",this.popup.style.opacity="0",this.popup.style.transform="translateY(-2px)",requestAnimationFrame(()=>{this.popup.style.transition="opacity 0.1s ease-in-out, transform 0.1s ease-in-out",this.popup.style.opacity="1",this.popup.style.transform="translateY(0)"})}hide(){"none"!==this.popup.style.display&&(this.popup.style.transition="opacity 0.1s ease-in-out, transform 0.1s ease-in-out",this.popup.style.opacity="0",this.popup.style.transform="translateY(-2px)",setTimeout(()=>{this.popup.style.display="none",this.popup.style.transition=""},100))}isPopup(t){return this.popup.contains(t)}isVisible(){return"none"!==this.popup.style.display}}class x{constructor(t,e,n,i){this.isRecording=!1,this.silenceTimer=null,this.document=t,this.editorView=e,this.onStateChange=n,this.insertText=i;const o=window.SpeechRecognition||window.webkitSpeechRecognition;o?(this.recognition=new o,this.recognition.continuous=!0,this.recognition.interimResults=!1,this.recognition.onresult=t=>{this.resetSilenceTimer();const e=t.results[t.results.length-1];if(e.isFinal){const t=e[0].transcript+" ";this.insertText(t)}},this.recognition.onerror=t=>{console.error("Speech recognition error:",t.error),"no-speech"!==t.error&&this.stopRecording()},this.recognition.onend=()=>{this.stopRecording()}):console.warn("Speech Recognition API not supported in this browser.")}toggleRecording(){this.isRecording?this.stopRecording():this.startRecording()}startRecording(){if(this.recognition)try{this.recognition.start(),this.isRecording=!0,this.onStateChange(!0),this.resetSilenceTimer()}catch(t){console.error("Failed to start speech recognition:",t)}}stopRecording(){if(this.recognition&&this.isRecording){try{this.recognition.stop()}catch(t){console.warn("Some problem occur during the stop recording . . . ",t)}this.isRecording=!1,this.onStateChange(!1),this.silenceTimer&&(clearTimeout(this.silenceTimer),this.silenceTimer=null)}}resetSilenceTimer(){this.silenceTimer&&clearTimeout(this.silenceTimer),this.silenceTimer=setTimeout(()=>{this.stopRecording()},4e3)}}class T extends e{constructor(t,e){var o,s,l,d,m,b,y,T,S,A,L,R,_;super(),this.savedSelection=null,this.debounceTimer=null;const{mainEditorId:O,toolbarId:B,popupToolbarId:H}=k(t,e);this.editorContainer=document.getElementById(O)||null,this.toolbarContainer=document.getElementById(B)||null;const N=document.getElementById(H)||null;if(!this.editorContainer||!this.toolbarContainer||!N)throw new Error("Editor element not found or incorrect element type.");this.document=new i,this.editorView=new c(this.editorContainer,this.document),this.toolbarView=new h(this.toolbarContainer),this.popupToolbarView=new E(N),this.linkPopupView=new w,this.hyperlinkHandler=new p(this.editorContainer,this.editorView,this.document),this.imageHandler=new I(this.editorContainer,this.document),this.undoRedoManager=new v(this.document,this.editorView),this.editorView.setImageHandler(this.imageHandler),this.imageHandler.setEditorView(this.editorView),this.document.setEditorView(this.editorView),this.document.setUndoRedoManager(this.undoRedoManager),this.hyperlinkHandler.setUndoRedoManager(this.undoRedoManager),this.linkPopupView.setCallbacks(t=>this.openLink(t),t=>this.unlinkText(t)),this.speechToTextHandler=new x(this.document,this.editorView,t=>{const e=document.getElementById("speechtotext");e&&(e.innerHTML=t?f.stop_microphone:f.start_microphone)},t=>{const[e,n]=this.getSelectionRange();n>e&&this.document.deleteRange(e,n,this.document.selectedBlockId,this.document.currentOffset);let i=e;this.document.insertAt(t,Object.assign({},this.currentAttributes),i,this.document.selectedBlockId,0,"","batch"),i+=t.length,this.setCursorPosition(i)});const P=document.getElementById("speechtotext");P&&(P.innerHTML="",P.insertAdjacentHTML("afterbegin",f.start_microphone)),this.currentAttributes={bold:!1,italic:!1,underline:!1,strikethrough:!1,undo:!1,redo:!1,hyperlink:!1},this.manualOverride=!1,this.lastPiece=null,this.toolbarView.on("toolbarAction",(t,e=[])=>this.handleToolbarAction(t,e)),this.popupToolbarView.on("popupAction",t=>this.handleToolbarAction(t)),this.document.on("documentChanged",()=>{if(0===this.document.blocks.length||1===this.document.blocks.length&&this.document.blocks[0].pieces.every(t=>""===t.text.trim()||"​"===t.text)){const t=document.getElementById("loadHtmlButton");t&&(t.selectedIndex=0)}this.editorView.render()}),this.document.on("documentChanged",()=>{var t;const e=this.document.getHtmlContent();this.emit("contentChange",{html:e,text:(null===(t=this.editorContainer)||void 0===t?void 0:t.textContent)||""})}),this.editorContainer.addEventListener("keydown",t=>{this.syncCurrentAttributesWithCursor(),this.handleKeydown(t)}),this.editorContainer.addEventListener("keyup",()=>this.syncCurrentAttributesWithCursor()),this.editorContainer.addEventListener("blur",()=>{this.hyperlinkHandler.hideHyperlinkViewButton()}),document.addEventListener("mouseup",()=>{this.syncCurrentAttributesWithCursor();const t=this.document.getAllSelectedDataIds();console.log(t,"dataId lntgerr")}),document.addEventListener("selectionchange",()=>{const t=window.getSelection();t&&!t.isCollapsed||(this.document.dataIds=[],this.document.selectAll=!1)}),null===(o=document.getElementById("fontColor"))||void 0===o||o.addEventListener("click",t=>{t.stopPropagation();const e=document.getElementById("colorWrapper"),n=document.getElementById("fontColorPicker");if(!e||!n)return;const i="block"===e.style.display;e.style.display=i?"none":"block"}),null===(s=document.getElementById("fontColorPicker"))||void 0===s||s.addEventListener("input",t=>{const e=t.target.value,[n,i]=this.getSelectionRange(),o=document.getElementById("fontColorIndicator");o&&(o.style.backgroundColor=e),this.document.dataIds.length>1?this.document.blocks.forEach(t=>{if(this.document.dataIds.includes(t.dataId)){this.document.selectedBlockId=t.dataId;let i=0;t.pieces.forEach(t=>{i+=t.text.length});let o=n-i;this.document.applyFontColor(o,i,e)}}):(this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.document.applyFontColor(n,i,e)},300))}),null===(l=document.getElementById("colorResetFont"))||void 0===l||l.addEventListener("click",()=>{const t=document.getElementById("fontColorPicker"),e=document.getElementById("fontColorIndicator");t&&(t.value="#000000",e&&(e.style.backgroundColor="#000000"),t.dispatchEvent(new Event("input")))}),document.addEventListener("click",t=>{var e;const n=t.target,i=document.getElementById("colorWrapper"),o=document.getElementById("colorBgWrapper"),s=document.getElementById("fontColor"),l=document.getElementById("bgColor");!i||n.closest("#colorWrapper")||n===s||(null==s?void 0:s.contains(n))||(i.style.display="none"),!o||n.closest("#colorBgWrapper")||n===l||(null==l?void 0:l.contains(n))||(o.style.display="none"),(null===(e=this.editorContainer)||void 0===e?void 0:e.contains(n))||n.closest(".hyperlink-popup")||this.hyperlinkHandler.hideHyperlinkViewButton()}),null===(d=document.getElementById("bgColor"))||void 0===d||d.addEventListener("click",t=>{t.stopPropagation();const e=document.getElementById("colorBgWrapper"),n=document.getElementById("bgColorPicker");if(!e||!n)return;const i="block"===e.style.display;e.style.display=i?"none":"block"}),null===(m=document.getElementById("bgColorPicker"))||void 0===m||m.addEventListener("input",t=>{const e=t.target.value,[n,i]=this.getSelectionRange(),o=document.getElementById("bgColorIndicator");o&&(o.style.backgroundColor=e),this.document.dataIds.length>1?this.document.blocks.forEach(t=>{if(this.document.dataIds.includes(t.dataId)){this.document.selectedBlockId=t.dataId;let i=0;t.pieces.forEach(t=>{i+=t.text.length});let o=n-i;this.document.applyBgColor(o,i,e)}}):(this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.document.applyBgColor(n,i,e)},300))}),null===(b=document.getElementById("colorResetBG"))||void 0===b||b.addEventListener("click",()=>{const t=document.getElementById("bgColorPicker"),e=document.getElementById("bgColorIndicator");t&&(t.value="#ffffff",e&&(e.style.backgroundColor="#ffffff"),t.dispatchEvent(new Event("input")))}),null===(y=document.getElementById("getHtmlButton"))||void 0===y||y.addEventListener("click",t=>{const e=this.document.getHtmlContent(!0);console.log("Editor HTML Content:",e),this.htmlToJsonParser=new C(e);const n=this.htmlToJsonParser.parse();console.log("htmltoJson",JSON.stringify(n,null,2),n),this.showAcknowledgement("HTML copied to clipboard",2e3)}),null===(T=document.getElementById("loadHtmlButton"))||void 0===T||T.addEventListener("change",t=>{this.undoRedoManager.saveUndoSnapshot();const e=t.target,n=e.options[e.selectedIndex].dataset.html||u.TEST_HTML_CODE;this.htmlToJsonParser=new C(n),console.log(this.htmlToJsonParser,"this.htmlToJsonParser");const i=this.htmlToJsonParser.parse();this.document.blocks=i,i.length>0&&(this.document.dataIds[0]=i[0].dataId,this.document.selectedBlockId=i[0].dataId),this.document.emit("documentChanged",this);const[o]=this.getSelectionRange();this.document.blocks.forEach(t=>{if(this.document.dataIds.includes(t.dataId)){this.document.selectedBlockId=t.dataId;let e=0;t.pieces.forEach(t=>{e+=t.text.length});let n=o-e;t.fontSize&&this.document.setFontSize(n,e,t.fontSize)}}),console.log("blocks",this.document.blocks,this.document.dataIds,this.document.currentOffset),console.log("htmltoJson",JSON.stringify(i,null,2),i)}),null===(S=document.getElementById("fontFamily"))||void 0===S||S.addEventListener("change",t=>{this.undoRedoManager.saveUndoSnapshot();const e=t.target.value,[n,i]=this.getSelectionRange();this.document.dataIds.length>1?this.document.blocks.forEach(t=>{if(this.document.dataIds.includes(t.dataId)){this.document.selectedBlockId=t.dataId;let i=0;t.pieces.forEach(t=>{i+=t.text.length});let o=n-i;this.document.setFontFamily(o,i,e)}}):this.document.setFontFamily(n,i,e)}),null===(A=document.getElementById("fontSize"))||void 0===A||A.addEventListener("change",t=>{this.undoRedoManager.saveUndoSnapshot();const e=t.target.value,[n,i]=this.getSelectionRange();this.document.dataIds.length>1?this.document.blocks.forEach(t=>{if(this.document.dataIds.includes(t.dataId)){this.document.selectedBlockId=t.dataId;let i=0;t.pieces.forEach(t=>{i+=t.text.length});let o=n-i;this.document.setFontSize(o,i,e)}}):this.document.setFontSize(n,i,e)}),null===(L=document.getElementById("alignLeft"))||void 0===L||L.addEventListener("click",()=>{console.log("alignment alignLeft",this.document.dataIds),this.document.dataIds.forEach(t=>this.document.setAlignment("left",t))}),null===(R=document.getElementById("alignCenter"))||void 0===R||R.addEventListener("click",()=>{console.log("alignment alignCenter",this.document.dataIds),this.document.dataIds.forEach(t=>this.document.setAlignment("center",t))}),null===(_=document.getElementById("alignRight"))||void 0===_||_.addEventListener("click",()=>{console.log("alignment alignRight",this.document.dataIds),this.document.dataIds.forEach(t=>this.document.setAlignment("right",t))}),this.editorContainer.addEventListener("keydown",t=>{if((t.ctrlKey||t.metaKey)&&!t.altKey){const e=t.key.toLowerCase();if(["b","i","u","h"].includes(e)){t.preventDefault();let n="b";switch(e){case"b":n="bold";break;case"i":n="italic";break;case"u":n="underline";break;case"h":n="hyperlink"}this.handleToolbarAction(n)}if("z"===e?(t.preventDefault(),this.undoRedoManager.undo()):"y"===e&&(t.preventDefault(),this.undoRedoManager.redo()),"a"===e){const t=this.document.handleCtrlASelection();this.document.selectAll=!0,console.log("Selected text is inside element with data-id:",t)}"l"===t.key?(t.preventDefault(),this.document.setAlignment("left",this.document.selectedBlockId)):"e"===t.key?(t.preventDefault(),this.document.setAlignment("center",this.document.selectedBlockId)):"r"===t.key&&(t.preventDefault(),this.document.setAlignment("right",this.document.selectedBlockId))}}),document.addEventListener("selectionchange",this.handleSelectionChange.bind(this)),this.editorContainer.addEventListener("click",t=>{const e=t.target;if("A"===e.tagName||e.closest("a")){t.preventDefault(),t.stopPropagation();const n="A"===e.tagName?e:e.closest("a");this.showLinkPopup(n,t.clientX,t.clientY)}else this.hideLinkPopup()}),document.addEventListener("click",t=>{this.linkPopupView.isPopup(t.target)||this.hideLinkPopup()}),this.document.emit("documentChanged",this.document),this.editorContainer.addEventListener("paste",t=>{var e,i;this.undoRedoManager.saveUndoSnapshot(),t.preventDefault();const o=null===(e=t.clipboardData)||void 0===e?void 0:e.getData("text/html"),[s,l]=this.getSelectionRange();l>s&&this.document.deleteRange(s,l,this.document.selectedBlockId,this.document.currentOffset);let d=[];if(o)d=g(o);else{const e=function(t){const e=[];let n,i=0;for(;null!==(n=r.exec(t));){const o=n.index;let s=n[0],l="";const r=s.match(/[.,!?;:)\]\}"']+$/);if(r&&(l=r[0],s=s.slice(0,-l.length)),a(t,o))continue;o>i&&e.push({text:t.substring(i,o),isUrl:!1});let d=s;d.startsWith("http")||(d="https://"+d),e.push({text:s,isUrl:!0,url:d}),l&&e.push({text:l,isUrl:!1}),i=o+n[0].length}return it.isUrl&&t.url?new n(t.text,Object.assign(Object.assign({},this.currentAttributes),{hyperlink:t.url})):new n(t.text,Object.assign({},this.currentAttributes)))}let c=s;for(const t of d)this.document.insertAt(t.text,Object.assign({},t.attributes),c,this.document.selectedBlockId,0,"","batch"),c+=t.text.length;this.setCursorPosition(c)}),this.editorContainer.addEventListener("dragover",t=>{t.preventDefault()}),this.editorContainer.addEventListener("drop",t=>{var e,i;t.preventDefault(),this.undoRedoManager.saveUndoSnapshot();const o=null===(e=t.dataTransfer)||void 0===e?void 0:e.getData("text/html"),[s,l]=this.getSelectionRange();l>s&&this.document.deleteRange(s,l,this.document.selectedBlockId,this.document.currentOffset);let r=[];if(o)r=g(o);else{const e=(null===(i=t.dataTransfer)||void 0===i?void 0:i.getData("text/plain"))||"";r=[new n(e,Object.assign({},this.currentAttributes))]}let a=s;for(const t of r)this.document.insertAt(t.text,Object.assign({},t.attributes),a,this.document.selectedBlockId,0,"","batch"),a+=t.text.length;this.setCursorPosition(a)})}getSelectionRange(){const t=o(this.editorView.container);return t?[t.start,t.end]:[0,0]}applyFontColor(t){const e=window.getSelection();if(!e||0===e.rangeCount)return;e.getRangeAt(0).toString()}handleToolbarAction(t,e=[]){const[n,i]=this.getSelectionRange();switch(t){case"orderedList":if(this.document.dataIds.length>1)this.document.toggleOrderedListForMultipleBlocks(this.document.dataIds);else{const t=this.document.selectedBlockId||this.document.dataIds[0];this.document.toggleOrderedList(t)}this.document.updateOrderedListNumbers();break;case"unorderedList":this.document.dataIds.forEach(t=>{this.document.toggleUnorderedList(t)});break;case"image":this.imageHandler.insertImage();break;case"speechtotext":this.speechToTextHandler.toggleRecording();break;default:if(n1?this.document.blocks.forEach(t=>{if(this.document.dataIds.includes(t.dataId)){this.document.selectedBlockId=t.dataId;let e=0;t.pieces.forEach(t=>{e+=t.text.length});let i=n-e;this.document.toggleBoldRange(i,e)}}):this.document.toggleBoldRange(n,i);break;case"italic":this.document.dataIds.length>1?this.document.blocks.forEach(t=>{if(this.document.dataIds.includes(t.dataId)){this.document.selectedBlockId=t.dataId;let e=0;t.pieces.forEach(t=>{e+=t.text.length});let i=n-e;this.document.toggleItalicRange(i,e)}}):this.document.toggleItalicRange(n,i);break;case"underline":this.document.dataIds.length>1?this.document.blocks.forEach(t=>{if(this.document.dataIds.includes(t.dataId)){this.document.selectedBlockId=t.dataId;let e=0;t.pieces.forEach(t=>{e+=t.text.length});let i=n-e;this.document.toggleUnderlineRange(i,e)}}):this.document.toggleUnderlineRange(n,i);break;case"strikethrough":this.document.dataIds.length>1?this.document.blocks.forEach(t=>{if(this.document.dataIds.includes(t.dataId)){this.document.selectedBlockId=t.dataId;let e=0;t.pieces.forEach(t=>{e+=t.text.length});let i=n-e;this.document.toggleStrikethroughRange(i,e)}}):this.document.toggleStrikethroughRange(n,i);break;case"hyperlink":this.hyperlinkHandler.hanldeHyperlinkClick(n,i,this.document.currentOffset,this.document.selectedBlockId,this.document.blocks)}else this.currentAttributes[t]=!this.currentAttributes[t],this.manualOverride=!0}this.toolbarView.updateActiveStates(this.currentAttributes)}handleSelectionChange(){var t,e;const n=window.getSelection();if(!n||0===n.rangeCount||!(null===(t=this.editorContainer)||void 0===t?void 0:t.contains(n.anchorNode)))return this.hyperlinkHandler.hideHyperlinkViewButton(),void this.popupToolbarView.hide();const[i]=this.getSelectionRange();if(this.imageHandler.currentCursorLocation=i,n.isCollapsed?(this.document.dataIds=[],this.document.selectAll=!1,this.popupToolbarView.hide()):(this.document.getAllSelectedDataIds(),this.document.dataIds.length===this.document.blocks.length&&this.document.blocks.length>0&&(this.document.selectAll=!0),this.popupToolbarView.show(n)),!n||0===n.rangeCount)return;n&&!0===n.isCollapsed&&(this.document.dataIds=[],this.document.selectAll=!1);const o=n.getRangeAt(0),s=(null===(e=o.startContainer.parentElement)||void 0===e?void 0:e.closest("[data-id]"))||o.startContainer;s instanceof HTMLElement&&(this.document.selectedBlockId=s.getAttribute("data-id")||(o.startContainer instanceof HTMLElement?o.startContainer.getAttribute("data-id"):null)),this.syncCurrentAttributesWithCursor()}handleKeydown(t){var e,i;const[o,s]=this.getSelectionRange();if(this.imageHandler.currentCursorLocation=o,"Enter"===t.key){t.preventDefault(),this.undoRedoManager.saveUndoSnapshot();const i=`data-id-${Date.now()}`,l=this.document.blocks.findIndex(t=>t.dataId===this.document.selectedBlockId),r=this.document.blocks[l],a=(null===(e=null==r?void 0:r.pieces)||void 0===e?void 0:e.length)>0?r.pieces[r.pieces.length-1]:null,d=a?Object.assign({},a.attributes):{fontFamily:"Arial",fontSize:"16px",fontColor:"#000000",bgColor:"#ffffff",bold:!1,italic:!1,underline:!1,strikethrough:!1};if(r&&"image"===r.type)this.document.blocks.splice(l+1,0,{dataId:i,class:"paragraph-block",pieces:[new n("​",d)],type:"text"}),this.document.emit("documentChanged",this),this.imageHandler.setCursorPostion(1,i);else if(!r||"ol"!==r.listType&&"ul"!==r.listType&&"li"!==r.listType){const t=this.getCurrentCursorBlock(),e=null==t?void 0:t.toString();if(e&&r&&"text"===r.type){const t=o-this.document.currentOffset,s=[],l=[];let a=0;for(const e of r.pieces){const i=a+e.text.length;if(i<=t)s.push(e.clone());else if(a>=t)l.push(e.clone());else{const i=t-a,o=e.text.slice(0,i),r=e.text.slice(i);o&&s.push(new n(o,Object.assign({},e.attributes))),r&&l.push(new n(r,Object.assign({},e.attributes)))}a=i}r.pieces=s.length>0?s:[new n("​",d)];const c=l.length>0?l:[new n("​",d)],h=this.addBlockAfter(this.document.blocks,e,{dataId:i,class:"paragraph-block",pieces:c,type:"text"});this.document.blocks=h}else this.document.blocks.push({dataId:i,class:"paragraph-block",pieces:[new n("​",d)],type:"text"})}else{let t={dataId:i,class:"paragraph-block",pieces:[new n("​",d)],type:"text"},e="";if("ol"===r.listType?(t.listType="li",t.listStart=r.listStart+1,t.parentId=r.dataId,e=r.dataId):"li"===r.listType?(t.listType="li",t.listStart=r.listStart+1,t.parentId=r.parentId,e=r.parentId):"ul"===r.listType&&(t.listType="ul",t.parentId=r.parentId||r.dataId),this.document.blocks.splice(l+1,0,t),"ol"===r.listType||"li"===r.listType)for(let t=l+2;tt.dataId===this.imageHandler.highLightedImageDataId);return this.imageHandler.deleteImage(),void this.imageHandler.setCursorPostion(1,this.document.blocks[t-1].dataId)}const e=window.getSelection();console.log(e,"selection lntgerr");if((this.document.selectAll||this.document.dataIds.length===this.document.blocks.length&&this.document.dataIds.length>0||this.document.dataIds.length>1)&&!(null===(i=window.getSelection())||void 0===i?void 0:i.isCollapsed)){this.undoRedoManager.saveUndoSnapshot();const t=this.document.dataIds[0],e=this.document.blocks.findIndex(e=>e.dataId===t);this.document.deleteBlocks();let i=null,o=0;if(0===this.document.blocks.length){const t=`data-id-${Date.now()}`;this.document.blocks.push({dataId:t,class:"paragraph-block",pieces:[new n(" ")],type:"text"}),i=t,o=0,this.editorView.render()}else if(et+e.text.length,0)}return void this.setCursorPosition(o,i)}if(s>o){this.undoRedoManager.saveUndoSnapshot();const t=Math.min(this.document.currentOffset,o);this.document.deleteRange(o,s,this.document.selectedBlockId,t,!0),this.setCursorPosition(o-1);const e=this.document.blocks.findIndex(t=>t.dataId===this.document.selectedBlockId);console.log(e,"index lntgerr");if(null===document.querySelector(`[data-id="${this.document.selectedBlockId}"]`)){let t=0;console.log(t," listStart lntgerr");const e=this.document.blocks.map((e,n)=>(void 0===(null==e?void 0:e.listType)&&null===(null==e?void 0:e.listType)||("ol"===(null==e?void 0:e.listType)?(t=1,e.listStart=1):"li"===(null==e?void 0:e.listType)&&(t+=1,e.listStart=t)),e));console.log(e,"blocks lntgerr"),this.document.emit("documentChanged",this)}}else o===s&&o>0&&(this.document.deleteRange(o-1,o,this.document.selectedBlockId,this.document.currentOffset,!0),this.setCursorPosition(o-1))}else if(1!==t.key.length||t.ctrlKey||t.metaKey||t.altKey){if("Delete"===t.key){if(t.preventDefault(),o===s){if(this.undoRedoManager.saveUndoSnapshot(),s>o){const t=Math.min(this.document.currentOffset,o);this.document.deleteRange(o,s,this.document.selectedBlockId,t),this.setCursorPosition(o)}else if(s>o)return this.undoRedoManager.saveUndoSnapshot(),void this.document.deleteRange(o,s,this.document.selectedBlockId);const t=this.document.blocks.findIndex(t=>t.dataId===this.document.selectedBlockId);if(-1===t)return;const e=this.document.blocks[t].pieces.reduce((t,e)=>t+e.text.length,0);o-this.document.currentOffseto&&(this.undoRedoManager.saveUndoSnapshot(),this.document.deleteRange(o,s,this.document.selectedBlockId),this.setCursorPosition(o))}this.hyperlinkHandler.hideHyperlinkViewButton()}}else t.preventDefault(),s>o&&(this.undoRedoManager.saveUndoSnapshot(),this.document.deleteRange(o,s,this.document.selectedBlockId,this.document.currentOffset,!1)),console.log("insertat",t.key,this.currentAttributes,o,this.document.selectedBlockId,this.document.currentOffset,"","",!t.isTrusted||!1),this.document.insertAt(t.key,this.currentAttributes,o,this.document.selectedBlockId,this.document.currentOffset,"","",!t.isTrusted||!1),this.setCursorPosition(o+1)}extractTextFromDataId(t){const e=window.getSelection();if(console.log("selection::",e),!e||0===e.rangeCount)return{remainingText:"",piece:null};const n=e.getRangeAt(0).startContainer;let i="";console.log(0,"count lntgerr");const o=this.document.blocks.filter(e=>{if(e.dataId===t)return e}),s=document.querySelector(`[data-id="${t}"]`),l=this.document.getCursorOffsetInParent(`[data-id="${t}"]`);let r=[],a=0;if(o[0].pieces.forEach((t,e)=>{i+=t.text,(null==l?void 0:l.innerText)===t.text&&(a=e,r.push(t))}),o[0].pieces.length>1&&o[0].pieces.forEach((t,e)=>{at.dataId===e);if(-1===i)return console.error(`Block with dataId "${e}" not found.`),t;return[...t.slice(0,i+1),n,...t.slice(i+1)]}syncCurrentAttributesWithCursor(){var t;const[e,n]=this.getSelectionRange();console.log("log1",{start:e,end:n});const i=this.document.blocks.findIndex(t=>t.dataId===this.document.selectedBlockId);if("image"===(null===(t=this.document.blocks[i])||void 0===t?void 0:t.type)?this.imageHandler.addStyleToImage(this.document.selectedBlockId||""):this.imageHandler.isImageHighlighted&&this.imageHandler.clearImageStyling(),e===n){const t=this.document.findPieceAtOffset(e,this.document.selectedBlockId);t?(t!==this.lastPiece&&(this.manualOverride=!1,this.lastPiece=t),this.manualOverride||(this.currentAttributes={bold:t.attributes.bold,italic:t.attributes.italic,underline:t.attributes.underline,strikethrough:t.attributes.strikethrough||!1,hyperlink:t.attributes.hyperlink||!1,fontFamily:t.attributes.fontFamily,fontSize:t.attributes.fontSize,fontColor:t.attributes.fontColor,bgColor:t.attributes.bgColor},this.toolbarView.updateActiveStates(this.currentAttributes),this.popupToolbarView.updateActiveStates(this.currentAttributes)),this.hyperlinkHandler.hideHyperlinkViewButton()):(this.hyperlinkHandler.hideHyperlinkViewButton(),this.manualOverride||(this.currentAttributes={bold:!1,italic:!1,underline:!1,strikethrough:!1,hyperlink:!1},this.toolbarView.updateActiveStates(this.currentAttributes),this.popupToolbarView.updateActiveStates(this.currentAttributes)),this.lastPiece=null)}else{this.hyperlinkHandler.hideHyperlinkViewButton();const t=this.document.isRangeEntirelyAttribute(e,n,"bold"),i=this.document.isRangeEntirelyAttribute(e,n,"italic"),o=this.document.isRangeEntirelyAttribute(e,n,"underline"),s=this.document.isRangeEntirelyAttribute(e,n,"strikethrough");this.currentAttributes={bold:t,italic:i,underline:o,strikethrough:s,hyperlink:!1},this.toolbarView.updateActiveStates(this.currentAttributes),this.popupToolbarView.updateActiveStates(this.currentAttributes)}}setCursorPosition(t,e=""){if(""===e)this.editorView.container.focus();else{const t=document.querySelector('[data-id="'+e+'"]');t&&t.focus()}const n=window.getSelection();if(!n)return;const i=document.createRange();let o=0;const s=[this.editorView.container];let l;for(;l=s.pop();)if(3===l.nodeType){const e=l,n=o+e.length;if(t>=o&&t<=n){i.setStart(e,t-o),i.collapse(!0);break}o=n}else if("BR"===l.tagName){if(t===o){i.setStartBefore(l),i.collapse(!0);break}o++}else{const t=l;let e=t.childNodes.length;for(;e--;)s.push(t.childNodes[e])}n.removeAllRanges(),n.addRange(i)}showAcknowledgement(t,e=2e3){const n=document.getElementById(u.TOAST_ID);n&&n.remove();const i=document.createElement("div");i.id=u.TOAST_ID,i.className="ti-toast",i.textContent=t||u.TOAST_DEFAULT_MESSAGE,document.body.appendChild(i),i.offsetHeight,i.classList.add(u.TOAST_SHOW_CLASS),setTimeout(()=>{i.classList.remove(u.TOAST_SHOW_CLASS),setTimeout(()=>i.remove(),200)},e||u.TOAST_DEFAULT_DURATION_MS)}showLinkPopup(t,e,n){this.linkPopupView.show(t,e,n)}hideLinkPopup(){this.linkPopupView.hide()}openLink(t){window.open(t,"_blank"),this.hideLinkPopup()}unlinkText(t){this.undoRedoManager.saveUndoSnapshot();const e=t.textContent||"",n=(this.editorView.container.textContent||"").indexOf(e);-1!==n&&(this.document.formatAttribute(n,n+e.length,"hyperlink",!1),this.editorView.render()),this.hideLinkPopup()}onContentChange(t){this.on("contentChange",t)}getContent(){return this.document.getHtmlContent()||""}getTextContent(){var t;return(null===(t=this.editorContainer)||void 0===t?void 0:t.textContent)||""}}window.TextIgniter=T,t.TextIgniter=T}); +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).TextIgniter={})}(this,function(t){"use strict";class e{constructor(){this.events={}}on(t,e){this.events[t]||(this.events[t]=[]),this.events[t].push(e)}emit(t,e){this.events[t]&&this.events[t].forEach(t=>t(e))}}class n{constructor(t,e={}){this.text=t;const n=document.getElementById("fontFamily"),i=document.getElementById("fontSize");let o="Arial",s="16px",l=document.getElementById("fontColorPicker"),r=document.getElementById("bgColorPicker");n&&(o=n.value),i&&(s=i.value);const a=e.fontColor||(l?l.value:"#000000"),d=e.bgColor||(r?r.value:"#ffffff");this.attributes={bold:e.bold||!1,italic:e.italic||!1,underline:e.underline||!1,strikethrough:e.strikethrough||!1,undo:e.undo||!1,redo:e.redo||!1,fontFamily:e.fontFamily||o,fontSize:e.fontSize||s,hyperlink:e.hyperlink||!1,fontColor:a,bgColor:d}}isBold(){return this.attributes.bold}setBold(t){this.attributes.bold=t}isItalic(){return this.attributes.italic}isUndo(){return this.attributes.undo}isRedo(){return this.attributes.redo}setItalic(t){this.attributes.italic=t}isUnderline(){return this.attributes.underline}setUnderline(t){this.attributes.underline=t}isStrikethrough(){return this.attributes.strikethrough||!1}setStrikethrough(t){this.attributes.strikethrough=t}setUndo(t){this.attributes.undo=t}setRedo(t){this.attributes.redo=t}clone(){return new n(this.text,Object.assign({},this.attributes))}hasSameAttributes(t){return this.attributes.bold===t.attributes.bold&&this.attributes.italic===t.attributes.italic&&this.attributes.underline===t.attributes.underline&&(this.attributes.strikethrough||!1)===(t.attributes.strikethrough||!1)&&this.attributes.undo===t.attributes.undo&&this.attributes.redo===t.attributes.redo&&this.attributes.fontFamily===t.attributes.fontFamily&&this.attributes.fontSize===t.attributes.fontSize&&this.attributes.italic===t.attributes.italic&&this.attributes.underline===t.attributes.underline&&this.attributes.hyperlink===t.attributes.hyperlink&&this.attributes.fontColor===t.attributes.fontColor&&this.attributes.bgColor===t.attributes.bgColor}getHyperlink(){return this.attributes.hyperlink||!1}setHyperlink(t){this.attributes.hyperlink=t}}class i extends e{get selectedBlockId(){return this._selectedBlockId}set selectedBlockId(t){if(this._selectedBlockId!==t){this._selectedBlockId=t;const e=this.getCursorOffset(document.querySelector('[id="editor"]')),n=this.getCursorOffset(document.querySelector('[data-id="'+t+'"]'));this.currentOffset=e-n}}constructor(){super(),this.dataIds=[],this.selectAll=!1,this._selectedBlockId=null,this.pieces=[new n("")],this.blocks=[{type:"text",dataId:"data-id-1734604240404",class:"paragraph-block",alignment:"left",pieces:[new n("​")]}],this.selectedBlockId="data-id-1734604240404",this.currentOffset=0}setEditorView(t){this.editorView=t}getPlainText(){return this.pieces.map(t=>t.text).join("")}setUndoRedoManager(t){this.undoRedoManager=t}insertAt(t,e,i,o="",s=0,l="",r="",a=!1){a||"batch"===r||this.undoRedoManager.saveUndoSnapshot(),console.log("inserted,",{start:i,text:t}),console.log("inserted,",this.blocks);let d=0,c=[],h=!1,u=0;""!==o&&null!==o&&(u=this.blocks.findIndex(t=>t.dataId===o),d=this.currentOffset);for(let o of this.blocks[u].pieces){const s=d+o.text.length;if(!h&&i<=s){const s=i-d;s>0&&c.push(new n(o.text.slice(0,s),Object.assign({},o.attributes))),c.push(new n(t,{bold:e.bold||!1,italic:e.italic||!1,underline:e.underline||!1,strikethrough:e.strikethrough||!1,hyperlink:e.hyperlink||!1})),st.dataId===i),-1===a)return;r=o}let c=-1;if(s&&t===r&&a>0&&e===t&&(c=a-1>=0&&"image"===this.blocks[a-1].type?a-2:a-1,c>=0&&this.blocks[c]))for(let t of this.blocks[c].pieces)l.push(t.clone()),d=!0;for(let i of this.blocks[a].pieces){const o=r+i.text.length,s=r;if(o<=t||s>=e)l.push(i.clone());else{const r=i.text;if(t>s){const e=r.slice(0,t-s);e.length>0&&l.push(new n(e,Object.assign({},i.attributes)))}if(e0&&l.push(new n(t,Object.assign({},i.attributes)))}}r=o}let h=this.mergePieces(l),u=!1;d&&c>=0?(!this.blocks[a]||"ol"!==this.blocks[a].listType&&"li"!==this.blocks[a].listType||(u=!0),this.blocks[c].pieces=h,this.blocks.splice(a,1)):0===h.length?this.blocks.length>1?(!this.blocks[a]||"ol"!==this.blocks[a].listType&&"li"!==this.blocks[a].listType||(u=!0),this.blocks.splice(a,1)):(h=[new n(" ")],this.blocks[a].pieces=h):this.blocks[a].pieces=h,u&&this.updateOrderedListNumbers(),this.emit("documentChanged",this)}deleteBlocks(){const t=this.blocks.some(t=>this.dataIds.includes(t.dataId)&&("ol"===t.listType||"li"===t.listType));this.blocks=this.blocks.filter(t=>{if(!this.dataIds.includes(t.dataId))return t}),this.dataIds=[],this.selectAll=!1,0===this.blocks.length&&this.blocks.push({dataId:`data-id-${Date.now()}`,class:"paragraph-block",type:"text",pieces:[new n("​")]}),t&&this.updateOrderedListNumbers(),this.emit("documentChanged",this)}getSelectedTextDataId(){const t=window.getSelection();if(!t||0===t.rangeCount)return null;const e=t.getRangeAt(0).startContainer,n=(e.nodeType===Node.TEXT_NODE?e.parentElement:e).closest("[data-id]");return(null==n?void 0:n.getAttribute("data-id"))||null}getAllSelectedDataIds(){var t;const e=window.getSelection();if(!e||0===e.rangeCount)return[];const n=e.getRangeAt(0),i=[],o=document.createNodeIterator(n.commonAncestorContainer,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT);let s;for(;s=o.nextNode();)if(n.intersectsNode(s)){const e=s.nodeType===Node.TEXT_NODE?s.parentElement:s,n=null===(t=null==e?void 0:e.closest("[data-id]"))||void 0===t?void 0:t.getAttribute("data-id");n&&!i.includes(n)&&i.push(n)}return this.removeExclusiveEndBlock(n,i),this.dataIds=i,console.log("selected id 3",this.dataIds,i),i}handleCtrlASelection(){const t=[],e=document.getElementById("editor");if(e){e.querySelectorAll("[data-id]").forEach(e=>{const n=e.getAttribute("data-id");n&&!t.includes(n)&&t.push(n)})}return this.dataIds=t,console.log("selected id 2",this.dataIds,t),t}getSelectedDataIds(){const t=window.getSelection();if(!t||0===t.rangeCount)return[];const e=t.getRangeAt(0),n=[],i=e.startContainer,o=e.endContainer,s=this.getDataIdFromNode(i),l=this.getDataIdFromNode(o);return s&&!n.includes(s)&&n.push(s),l&&!n.includes(l)&&n.push(l),this.removeExclusiveEndBlock(e,n),this.dataIds=n,console.log("selected id 1",this.dataIds,n),n}getDataIdFromNode(t){var e;const n=t.nodeType===Node.TEXT_NODE?t.parentElement:t;return(null===(e=null==n?void 0:n.closest("[data-id]"))||void 0===e?void 0:e.getAttribute("data-id"))||null}getCursorOffset(t){const e=window.getSelection();if(!e||0===e.rangeCount)return-1;const n=e.getRangeAt(0);let i=0;const o=t=>{if(t===n.startContainer)return i+=n.startOffset,!0;t.nodeType===Node.TEXT_NODE&&(i+=(t.textContent||"").length);for(const e of Array.from(t.childNodes))if(o(e))return!0;return!1};return o(t),i}formatAttribute(t,e,i,o){console.log("formatAttribute",t,e,i,o);let s=[],l=0,r=-1;if(""!==this.selectedBlockId&&null!==this.selectedBlockId){if(r=this.blocks.findIndex(t=>t.dataId===this.selectedBlockId),-1===r)return;l=this.currentOffset}for(let a of this.blocks[r].pieces){const r=l+a.text.length;if(r<=t||l>=e)s.push(a.clone());else{const r=l,d=a.text,c=Math.max(t-r,0),h=Math.min(e-r,d.length);c>0&&s.push(new n(d.slice(0,c),Object.assign({},a.attributes)));const u=new n(d.slice(c,h),Object.assign({},a.attributes));("bold"!==i&&"italic"!==i&&"underline"!==i&&"strikethrough"!==i&&"undo"!==i&&"redo"!==i&&"hyperlink"!==i||"boolean"!=typeof o)&&("fontFamily"!==i&&"fontSize"!==i&&"hyperlink"!==i&&"fontColor"!==i&&"bgColor"!==i||"string"!=typeof o)||(u.attributes[i]=o),s.push(u),he.dataId===t);if(-1===n)return;const i=this.blocks[n];"ol"===i.listType||"li"===i.listType?(i.listType=null,i.listStart=void 0,i.parentId=void 0):(i.listType="ol",i.listStart=1,i.parentId=i.dataId),this.updateOrderedListNumbers(),this.emit("documentChanged",this)}toggleOrderedListForMultipleBlocks(t){if(0===t.length)return;const e=t.sort((t,e)=>this.blocks.findIndex(e=>e.dataId===t)-this.blocks.findIndex(t=>t.dataId===e));if(e.every(t=>{const e=this.blocks.find(e=>e.dataId===t);return e&&("ol"===e.listType||"li"===e.listType)}))e.forEach(t=>{const e=this.blocks.find(e=>e.dataId===t);e&&(e.listType=null,e.listStart=void 0,e.parentId=void 0)});else{const t=e[0];e.forEach((e,n)=>{const i=this.blocks.find(t=>t.dataId===e);i&&(0===n?(i.listType="ol",i.listStart=1,i.parentId=t):(i.listType="li",i.listStart=n+1,i.parentId=t))})}this.updateOrderedListNumbers(),this.emit("documentChanged",this)}toggleUnorderedList(t){const e=this.blocks.findIndex(e=>e.dataId===t);if(-1===e)return;const n=this.blocks[e];n.listType="ul"===n.listType?null:"ul",this.emit("documentChanged",this)}updateOrderedListNumbers(){let t=1,e=null;for(let n=0;nt.focus(),0)}else this.editorView.container.focus();const i=window.getSelection();if(!i)return;const o=document.createRange();let s=0;const l=[this.editorView.container];let r;const a=(null===(n=this.editorView.container.textContent)||void 0===n?void 0:n.length)||0;if(!(t<0||t>a)){for(;r=l.pop();)if(3===r.nodeType){const e=r,n=s+e.length;if(t>=s&&t<=n){o.setStart(e,Math.min(t-s,e.length)),o.collapse(!0);break}s=n}else if("BR"===r.tagName){if(t===s){o.setStartBefore(r),o.collapse(!0);break}s++}else{const t=r;let e=t.childNodes.length;for(;e--;)l.push(t.childNodes[e])}i.removeAllRanges(),i.addRange(o)}}toggleBoldRange(t,e,n=""){const i=this.isRangeEntirelyAttribute(t,e,"bold");this.formatAttribute(t,e,"bold",!i)}toggleItalicRange(t,e,n=""){const i=this.isRangeEntirelyAttribute(t,e,"italic");this.formatAttribute(t,e,"italic",!i)}toggleUnderlineRange(t,e,n=""){const i=this.isRangeEntirelyAttribute(t,e,"underline");this.formatAttribute(t,e,"underline",!i)}toggleStrikethroughRange(t,e,n=""){const i=this.isRangeEntirelyAttribute(t,e,"strikethrough");this.formatAttribute(t,e,"strikethrough",!i)}toggleUndoRange(t,e,n=""){const i=this.isRangeEntirelyAttribute(t,e,"undo");this.formatAttribute(t,e,"undo",!i)}toggleRedoRange(t,e){const n=this.isRangeEntirelyAttribute(t,e,"redo");this.formatAttribute(t,e,"redo",!n)}applyFontColor(t,e,n,i=""){tt.dataId===this.selectedBlockId);if(-1===s)return!1;for(let l of this.blocks[s].pieces){const s=i+l.text.length;if(s>t&&it+e.text.length,0);if(i.dataId==e){let e=null;for(let o of i.pieces){const i=n,s=i+o.text.length;if(t>=i&&tt.dataId===e);n&&(n.alignment=t,this.emit("documentChanged",this))}getHtmlContent(t=!1){const e=document.getElementById("editor");if(!e)return void console.error("Editor container not found.");const n=e.innerHTML;return t&&navigator.clipboard.writeText(n).then(()=>{console.log("HTML copied to clipboard!")}).catch(t=>console.error("Failed to copy HTML:",t)),n}getCursorOffsetInParent(t){var e;console.log("textPosition -1:vicky",t);const n=document.querySelector(t);if(!n)return null;const i=window.getSelection();if(!i||0===i.rangeCount)return null;const o=i.getRangeAt(0);if(!n.contains(o.startContainer))return null;let s=0,l=null;const r=document.createTreeWalker(n,NodeFilter.SHOW_TEXT,null);let a=null;for(;r.nextNode();){const t=r.currentNode;if(console.log(t,"textPosition - currentNode: vicky"),t===o.startContainer){s+=o.startOffset,l=t,a=t.parentElement;break}s+=(null===(e=t.textContent)||void 0===e?void 0:e.length)||0}return console.log({offset:s,childNode:l,innerHTML:a.innerHTML,innerText:a.innerText},"textPosition - return values: vicky"),{offset:s,childNode:l,innerHTML:a.innerHTML,innerText:a.innerText}}removeExclusiveEndBlock(t,e){if(e.length<=1)return;const n=t.endContainer,i=t.endOffset;let o=!1;if((n.nodeType===Node.TEXT_NODE||n.nodeType===Node.ELEMENT_NODE)&&(o=0===i),!o)return;const s=this.getDataIdFromNode(n);if(!s)return;if(s!==this.getDataIdFromNode(t.startContainer)&&e.includes(s)){const t=e.lastIndexOf(s);t>-1&&e.splice(t,1)}}}function o(t){const e=window.getSelection();if(!e||0===e.rangeCount)return null;const n=e.getRangeAt(0),i=n.cloneRange();i.selectNodeContents(t),i.setEnd(n.startContainer,n.startOffset);const o=i.toString().length;i.setEnd(n.endContainer,n.endOffset);return{start:o,end:i.toString().length}}function s(t,e){if(!e)return;let n=0;const i=document.createRange();i.setStart(t,0),i.collapse(!0);const o=[t];let s,l=!1,r=!1;for(;!r&&(s=o.pop());)if(3===s.nodeType){const t=s,o=n+t.length;!l&&e.start>=n&&e.start<=o&&(i.setStart(t,e.start-n),l=!0),l&&e.end>=n&&e.end<=o&&(i.setEnd(t,e.end-n),r=!0),n=o}else if("BR"===s.tagName)l||e.start!==n||(i.setStartBefore(s),l=!0),l&&e.end===n&&(i.setEndBefore(s),r=!0),n++;else{const t=s;let e=t.childNodes.length;for(;e--;)o.push(t.childNodes[e])}const a=window.getSelection();a&&(a.removeAllRanges(),a.addRange(i))}function l(t){const e=o(t.container);return e?[e.start,e.end]:[0,0]}const r=/((https?:\/\/|www\.)[\w\-._~:\/?#[\]@!$&'()*+,;=%]+|\b[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(?:\/[\w\-._~:\/?#[\]@!$&'()*+,;=%]*)?)/g;function a(t,e){return e>0&&"@"===t[e-1]}function d(t){if(!t)return t;let e=t.trim();const n=e.match(/^https?:\/\/[\w.-]+(?::\d+)?\/(https?:\/\/.*)$/);return n&&(e=n[1]),/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(e)?e:e.startsWith("//")?"https:"+e:"https://"+e}class c{constructor(t,e){this.container=t,this.document=e}setImageHandler(t){this.imageHandler=t}render(){const t=o(this.container);this.container.innerHTML="",this.document.blocks.forEach(t=>{var e;if(""!==t.dataId){let n;if("image"===t.type){if(n=document.createElement("div"),n.setAttribute("data-id",t.dataId),n.setAttribute("class",t.class),n.setAttribute("type",t.type),n.style.textAlign=t.alignment||"left",t.image)if(this.imageHandler&&"function"==typeof this.imageHandler.createImageFragment)n.appendChild(this.imageHandler.createImageFragment(t.image,t.dataId));else{const e=document.createElement("img");e.src=t.image,n.appendChild(e)}}else if("ol"===t.listType||"li"===t.listType?(n=document.createElement("ol"),n.setAttribute("start",(null===(e=null==t?void 0:t.listStart)||void 0===e?void 0:e.toString())||"1")):n="ul"===t.listType?document.createElement("ul"):document.createElement("div"),n.setAttribute("data-id",t.dataId),n.setAttribute("class",t.class),n.setAttribute("type",t.type),n.style.textAlign=t.alignment||"left",Array.isArray(t.pieces))if("ol"===t.listType||"ul"===t.listType||"li"===t.listType){const e=document.createElement("li");t.pieces.forEach(t=>{e.appendChild(this.renderPiece(t))}),n.appendChild(e)}else t.pieces.forEach(t=>{n.appendChild(this.renderPiece(t))});this.container.appendChild(n)}}),s(this.container,t)}renderPiece(t){const e=t.text.split("\n");return this.wrapAttributes(e,t.attributes)}wrapAttributes(t,e){const n=document.createDocumentFragment();return t.forEach((i,o)=>{let s=document.createTextNode(i);if(e.strikethrough){const t=document.createElement("s");t.appendChild(s),s=t}if(e.underline){const t=document.createElement("u");t.appendChild(s),s=t}if(e.italic){const t=document.createElement("em");t.appendChild(s),s=t}if(e.bold){const t=document.createElement("strong");t.appendChild(s),s=t}const l=document.getElementById("fontFamily"),r=document.getElementById("fontSize");let a="Arial",c="16px";l&&(a=l.value),r&&(c=r.value);const h=document.createElement("span");if(h.style.fontFamily=e.fontFamily||a,h.style.fontSize=e.fontSize||c,e.fontColor&&"string"==typeof e.fontColor&&(h.style.color=e.fontColor),e.bgColor&&"string"==typeof e.bgColor&&(h.style.backgroundColor=e.bgColor),e.hyperlink&&"string"==typeof e.hyperlink){const t=document.createElement("a");t.href=d(e.hyperlink),t.appendChild(s),s=t}h.appendChild(s),s=h,n.appendChild(s),o{t.addEventListener("mousedown",t=>{t.preventDefault()})}),this.container.addEventListener("click",t=>{const e=t.target.closest("button");if(e){const t=e.getAttribute("data-action");t&&this.emit("toolbarAction",t)}})}updateActiveStates(t){if(this.container.querySelectorAll("button").forEach(e=>{const n=e.getAttribute("data-action");let i=!1;"bold"===n&&t.bold&&(i=!0),"italic"===n&&t.italic&&(i=!0),"underline"===n&&t.underline&&(i=!0),"strikethrough"===n&&t.strikethrough&&(i=!0),"hyperlink"===n&&t.hyperlink&&(i=!0),"undo"===n&&t.undo&&(i=!0),"redo"===n&&t.redo&&(i=!0),e.classList.toggle("active",i)}),this.container.querySelectorAll("select").forEach(e=>{const n=e.getAttribute("data-action");"fontFamily"===n&&t.fontFamily&&(e.value=t.fontFamily),"fontSize"===n&&t.fontSize&&(e.value=t.fontSize)}),t.fontColor){const e=document.getElementById("fontColorPicker");e&&(e.value=t.fontColor,e.dispatchEvent(new Event("input",{bubbles:!0})))}if(t.bgColor){const e=document.getElementById("bgColorPicker");e&&(e.value=t.bgColor,e.dispatchEvent(new Event("input",{bubbles:!0})))}}}const u={TOOLBAR_CLASSNAME:"toolbar",TOOLBAR_ID:"toolbar",EDITOR_CLASSNAME:"editor",EDITOR_ID:"editor",EDITOR_ELEMENT_NT_FOUND:"Editor element not found or incorrect element type.",FONT_FAMILY_SELECT_ID:"fontFamily",FONT_SIZE_SELECT_ID:"fontSize",FONT_COLOR_WRAPPER_ID:"fontColorWrapper",FONT_COLOR_ID:"fontColor",FONT_COLOR_PICKER_WRAPPER_ID:"colorWrapper",FONT_COLOR_PICKER_ID:"fontColorPicker",FONT_COLOR_RESET_ID:"colorResetFont",BG_COLOR_WRAPPER_ID:"bgColorWrapper",BG_COLOR_ID:"bgColor",BG_COLOR_PICKER_WRAPPER_ID:"colorBgWrapper",BG_COLOR_RESET_ID:"colorResetBG",BG_COLOR_PICKER_ID:"bgColorPicker",GET_HTML_BUTTON_ID:"getHtmlButton",LOAD_HTML_BUTTON_ID:"loadHtmlButton",HYPERLINK_CONTAINER_ID:"hyperlink-container",HYPERLINK_INPUT_ID:"hyperlink-input",HYPERLINK_PLACEHOLDER:"Enter a URL...",HYPERLINK_APPLY_BTN_ID:"apply-hyperlink",HYPERLINK_CANCEL_BTN_ID:"cancel-hyperlink",VIEW_HYPERLINK_CONTAINER_ID:"hyperlink-container-view",VIEW_HYPERLINK_LABEL_ID:"hyperlink-view-span",VIEW_HYPERLINK_ANCHOR_ID:"hyperlink-view-link",TEMPORARY_SELECTION_HIGHLIGHT_CLASS:"temporary-selection-highlight",PARAGRAPH_BLOCK_CLASS:"paragraph-block",IMAGE_CROSS_CLASS:"image-cross",TEST_HTML_CODE:'
ajsh diujaksdajsh diujaksdajsh
diujaksdasd 98hasiudasdh 98
This is a t this is a test work
This is a test work. this is a test work
da90 uasd y98asiodoiasda90 uasd y98asiodoiasda90 uasd y98asioda
sdjasdjasdja9sudoija9sudoija9sudoija90sdoa90sdoa90sdo
',TEST_BLOG_POST_HTML_CODE:'
Blog Post Title
Start writing your post here...
',TEST_NEWSLATER_HTML_CODE:'
Weekly Newsletter
Hello subscribers,
',TEST_RESUME_HTML_CODE:'
John Doe
Experience
• Role 1
',TEST_EMAIL_HTML_CODE:'
Subject: Important Update
Hi Team,
',TEST_MEETING_HTML_CODE:'
Meeting Minutes
Attendees:
Action Items:
',POPUP_TOOLBAR_CLASSNAME:"popup-toolbar",POPUP_TOOLBAR_ID:"popup-toolbar",TOAST_ID:"ti-toast",TOAST_SHOW_CLASS:"ti-toast--show",TOAST_DEFAULT_MESSAGE:"HTML copied to clipboard",TOAST_DEFAULT_DURATION_MS:2e3};class p{constructor(t,e,n){this.savedSelection=null,this.clickOutsideHandler=null,this.editorContainer=t,this.editorView=e,this.document=n}setUndoRedoManager(t){this.undoRedoManager=t}hanldeHyperlinkClick(t,e,n,i,o){const s=this.getCommonHyperlinkInRange(t,e,n,i,o);this.showHyperlinkInput(s)}getCommonHyperlinkInRange(t,e,n,i,o){let s=n,l=0;i&&(l=o.findIndex(t=>t.dataId===i));const r=o[l].pieces;let a=null;for(let n of r){const i=s+n.text.length;if(i>t&&s0){const t=c.getRangeAt(0);let o=null;if(t&&"function"==typeof t.getBoundingClientRect)o=t.getBoundingClientRect();else if(t&&"function"==typeof t.getClientRects){const n=null===(e=t.getClientRects)||void 0===e?void 0:e.call(t);o=n&&n.length?n[0]:null}(!o||Number.isNaN(o.top)&&Number.isNaN(o.left))&&(o=this.editorView.container.getBoundingClientRect());const l=(null===window||void 0===window?void 0:window.scrollY)||0,r=(null===window||void 0===window?void 0:window.scrollX)||0;s.style.top=`${(null!==(n=o.bottom)&&void 0!==n?n:o.top)+l+5}px`,s.style.left=`${(null!==(i=o.left)&&void 0!==i?i:0)+r}px`}l.value=t||"",this.savedSelection=o(this.editorView.container),this.highlightSelection(),l.focus(),r.onclick=null,a.onclick=null;const h=this.document.dataIds,u=()=>{const t=d(l.value.trim());t&&this.applyHyperlink(t,h),s.style.display="none"};r.onclick=u,l.onkeydown=t=>{"Enter"===t.key&&(t.preventDefault(),u())},a.onclick=()=>{this.removeHyperlink(h),s.style.display="none"}}}highlightSelection(){this.removeHighlightSelection();const t=window.getSelection();if(t&&t.rangeCount>0){const e=t.getRangeAt(0),n=document.createElement("span");n.className=u.TEMPORARY_SELECTION_HIGHLIGHT_CLASS,n.appendChild(e.extractContents()),e.insertNode(n),t.removeAllRanges();const i=document.createRange();i.selectNodeContents(n),t.addRange(i)}}removeHighlightSelection(){var t;const e=null===(t=this.editorContainer)||void 0===t?void 0:t.querySelectorAll(`span.${u.TEMPORARY_SELECTION_HIGHLIGHT_CLASS}`);null==e||e.forEach(t=>{const e=t.parentNode;if(e){for(;t.firstChild;)e.insertBefore(t.firstChild,t);e.removeChild(t)}})}applyHyperlink(t,e){this.undoRedoManager.saveUndoSnapshot(),this.removeHighlightSelection(),s(this.editorView.container,this.savedSelection);const[n,i]=l(this.editorView);if(n1?this.document.blocks.forEach(t=>{if(e.includes(t.dataId)){this.document.selectedBlockId=t.dataId;let e=0;t.pieces.forEach(t=>{e+=t.text.length});let i=n-e;this.document.formatAttribute(i,e,"hyperlink",o)}}):this.document.formatAttribute(n,i,"hyperlink",o),this.editorView.render();const s=window.getSelection();s&&s.removeAllRanges(),this.editorView.container.focus()}this.savedSelection=null}removeHyperlink(t){this.undoRedoManager.saveUndoSnapshot(),this.removeHighlightSelection(),s(this.editorView.container,this.savedSelection);const[e,n]=l(this.editorView);e1?this.document.blocks.forEach(n=>{if(t.includes(n.dataId)){this.document.selectedBlockId=n.dataId;let t=0;n.pieces.forEach(e=>{t+=e.text.length});let i=e-t;this.document.formatAttribute(i,t,"hyperlink",!1)}}):this.document.formatAttribute(e,n,"hyperlink",!1),this.editorView.render(),s(this.editorView.container,this.savedSelection),this.editorView.container.focus()),this.savedSelection=null}addClickOutsideListener(t){this.removeClickOutsideListener(),this.clickOutsideHandler=e=>{t&&!t.contains(e.target)&&this.hideHyperlinkViewButton()},setTimeout(()=>{document.addEventListener("click",this.clickOutsideHandler)},100)}removeClickOutsideListener(){this.clickOutsideHandler&&(document.removeEventListener("click",this.clickOutsideHandler),this.clickOutsideHandler=null)}showHyperlinkViewButton(t){var e,n,i;const o=document.getElementById(u.VIEW_HYPERLINK_CONTAINER_ID),s=document.getElementById(u.VIEW_HYPERLINK_ANCHOR_ID);if(o&&s){o.style.display="block";const l=window.getSelection();if(l&&l.rangeCount>0){const t=l.getRangeAt(0);let s=null;if(t&&"function"==typeof t.getBoundingClientRect)s=t.getBoundingClientRect();else if(t&&"function"==typeof t.getClientRects){const n=null===(e=t.getClientRects)||void 0===e?void 0:e.call(t);s=n&&n.length?n[0]:null}s||(s=this.editorView.container.getBoundingClientRect());const r=(null===window||void 0===window?void 0:window.scrollY)||0,a=(null===window||void 0===window?void 0:window.scrollX)||0;s&&(o.style.top=`${(null!==(n=s.bottom)&&void 0!==n?n:s.top)+r+5}px`,o.style.left=`${(null!==(i=s.left)&&void 0!==i?i:0)+a}px`)}t&&(s.innerText=t,s.href=d(t))}this.addClickOutsideListener(o)}hideHyperlinkViewButton(){const t=document.getElementById(u.VIEW_HYPERLINK_CONTAINER_ID);t&&(t.style.display="none"),this.removeClickOutsideListener()}}function g(t){return m((new DOMParser).parseFromString(t,"text/html").body,{bold:!1,italic:!1,underline:!1,hyperlink:!1})}function m(t,e){let i=Object.assign({},e);const o=[];if(t instanceof HTMLElement){if("A"===t.tagName){const e=t.getAttribute("href");e&&(i.hyperlink=e)}"STRONG"!==t.tagName&&"B"!==t.tagName||(i.bold=!0),"EM"!==t.tagName&&"I"!==t.tagName||(i.italic=!0),"U"===t.tagName&&(i.underline=!0),t.childNodes.forEach(t=>{o.push(...m(t,i))})}else if(t instanceof Text){const e=t.nodeValue||"";""!==e.trim()&&o.push(new n(e,Object.assign({},i)))}return o}const f={bold:'\n Bold\n \n ',italic:'\n Italic\n \n ',underline:'\n Underline\n \n ',strikethrough:'\n Strikethrough\n \n ',subscript:'\n Subscript\n \n ',superscript:'\n Superscript\n \n ',left_align:'\n Left Align\n \n ',center_align:'\n Center Align\n ',right_align:'\n Right Align',justify:'\n Justify\n ',bullet_list:'\n Bullet List',numbered_list:'\n Numbererd List\n \n ',insert_table:'\n Insert Table\n \n ',insert_layout:'\n Insert Layout\n \n ',heading:'\n Heading\n \n ',hyperlink:'\n Hyperlink\n \n \n ',image:'\n Insert Image\n \n ',stop_microphone:' \n \n \x3c!--!Font Awesome Free v7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--\x3e\n \n \n ',start_microphone:'\n \n \x3c!--!Font Awesome Free v7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--\x3e\n \n \n ',emoji:'\n Emoji\n \n \n \n \n '},b={dropdowns:["fontFamily","fontSize"],colors:["fontColor","bgColor"],formatting:["bold","italic","underline","strikethrough"],alignment:["alignLeft","alignCenter","alignRight"],lists:["unorderedList","orderedList"],media:["hyperlink","image","emoji"],utility:["getHtmlContent","loadHtmlContent"]};function y(){const t=document.createElement("div");return t.className="toolbar-separator",t}function k(t,e){const n=u.EDITOR_ID,i=u.TOOLBAR_ID,o=u.POPUP_TOOLBAR_ID,s=["Arial","Times New Roman","Courier New","Verdana"],l=["12px","14px","16px","18px","20px"],r=document.getElementById(t);if(!r)throw new Error(u.EDITOR_ELEMENT_NT_FOUND);r.classList.add("editor-container");const a=document.createElement("div");a.className=u.TOOLBAR_CLASSNAME,a.id=i,r.appendChild(a),(null==e?void 0:e.showToolbar)||(a.style.display="none");const d=document.createElement("div");d.id=n,d.className=u.EDITOR_CLASSNAME,d.contentEditable="true",r.appendChild(d);const c={bold:"B",italic:"I",underline:"U",hyperlink:"🔗",alignLeft:"⇤",alignCenter:"↔",alignRight:"⇥",unorderedList:"•",orderedList:"1.",fontFamily:"fontFamily",fontSize:"fontSize",fontColor:"A",subscript:"X2",superscript:"X2",justify:"⇄",insert_table:"⊢",insert_layout:"❐",heading:"H",image:"📷",colors:"🎨"},h={bold:"Bold (Ctrl+B)",italic:"Italic (Ctrl+I)",underline:"Underline (Ctrl+U)",strikethrough:"Strikethrough",hyperlink:"Insert Link (Ctrl+H)",alignLeft:"Align Left (Ctrl+L)",alignCenter:"Align Center (Ctrl+E)",alignRight:"Align Right (Ctrl+R)",unorderedList:"Bullet List",orderedList:"Numbered List",fontColor:"Text Color",bgColor:"Highlight Color",image:"Insert Image",emoji:"Emoji",getHtmlContent:"Get HTML",loadHtmlContent:"Load HTML"},p=[{feature:"alignLeft",id:"alignLeft",icon:f.left_align},{feature:"alignCenter",id:"alignCenter",icon:f.center_align},{feature:"alignRight",id:"alignRight",icon:f.right_align},{feature:"unorderedList",id:"unorderedList",icon:f.bullet_list},{feature:"orderedList",id:"orderedList",icon:f.numbered_list},{feature:"hyperlink",id:"hyperlink",icon:f.hyperlink},{feature:"emoji",id:"emoji",icon:f.emoji},{feature:"strikethrough",id:"strikethrough",icon:f.strikethrough}],g=(t,e)=>{const n=document.createElement("select");return n.dataset.action=t,n.id=t,e.forEach(t=>{const e=document.createElement("option");e.value=t,e.textContent=t,n.appendChild(e)}),n},m=document.createElement("div");m.id=o,m.className=u.POPUP_TOOLBAR_CLASSNAME,m.style.display="none",r.appendChild(m),e.popupFeatures&&e.popupFeatures.forEach((t,e)=>{e>0&&"hyperlink"===t&&m.appendChild(y());const n=p.find(e=>e.feature===t)||{icon:c[t]||t},i=document.createElement("button");i.dataset.action=t,i.innerHTML=n.icon,i.dataset.tooltip=h[t]||t.split("_").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" "),m.appendChild(i)});let k=null;e.features.forEach((t,n)=>{const i=function(t){for(const[e,n]of Object.entries(b))if(n.includes(t))return e;return null}(t);if(n>0&&i&&k&&i!==k&&a.appendChild(y()),k=i,"fontFamily"===t){const t=g(u.FONT_FAMILY_SELECT_ID,s);a.appendChild(t)}else if("fontSize"===t){const t=g(u.FONT_SIZE_SELECT_ID,l);a.appendChild(t)}else if("fontColor"===t){if(document.getElementById(u.FONT_COLOR_WRAPPER_ID))return;const t=document.createElement("span");t.id=u.FONT_COLOR_WRAPPER_ID,t.style.display="inline-flex",t.style.alignItems="center",t.style.position="relative",t.style.gap="4px";const e=document.createElement("button");e.id=u.FONT_COLOR_ID,e.type="button",e.dataset.tooltip=h.fontColor,e.innerHTML='A',t.appendChild(e);const n=document.createElement("div");n.id=u.FONT_COLOR_PICKER_WRAPPER_ID,n.style.display="none",n.style.position="absolute",n.style.top="100%",n.style.left="0",n.style.marginTop="4px",n.style.zIndex="1000",n.style.backgroundColor="#ffffff",n.style.border="1px solid #d1d1d1",n.style.borderRadius="4px",n.style.padding="8px",n.style.boxShadow="0 2px 8px rgba(0,0,0,0.15)",n.style.width="135px";const i=document.createElement("input");i.type="color",i.id=u.FONT_COLOR_PICKER_ID,i.setAttribute("data-action","fontColor"),i.style.width="100%",i.style.height="32px",i.style.border="1px solid #d1d1d1",i.style.borderRadius="4px",i.style.cursor="pointer",i.style.marginBottom="8px",i.value="#000000",n.appendChild(i);const o=document.createElement("button");o.id=u.FONT_COLOR_RESET_ID,o.type="button",o.textContent="Reset",o.style.display="block",o.style.width="100%",o.style.padding="6px 12px",o.style.fontSize="12px",o.style.border="1px solid #000000",o.style.borderRadius="4px",o.style.backgroundColor="#f8f8f8",o.style.cursor="pointer",o.style.transition="background-color 0.2s",o.onmouseenter=()=>o.style.backgroundColor="#e8e8e8",o.onmouseleave=()=>o.style.backgroundColor="#f8f8f8",n.appendChild(o),t.appendChild(n),a.appendChild(t)}else if("bgColor"===t){if(document.getElementById(u.BG_COLOR_WRAPPER_ID))return;const t=document.createElement("span");t.id=u.BG_COLOR_WRAPPER_ID,t.style.display="inline-flex",t.style.alignItems="center",t.style.position="relative",t.style.gap="4px";const e=document.createElement("button");e.id=u.BG_COLOR_ID,e.type="button",e.dataset.tooltip=h.bgColor,e.innerHTML='B',t.appendChild(e);const n=document.createElement("div");n.id=u.BG_COLOR_PICKER_WRAPPER_ID,n.style.display="none",n.style.position="absolute",n.style.top="100%",n.style.left="0",n.style.marginTop="4px",n.style.zIndex="1000",n.style.backgroundColor="#ffffff",n.style.border="1px solid #000000",n.style.borderRadius="4px",n.style.padding="8px",n.style.boxShadow="0 2px 8px rgba(0,0,0,0.15)",n.style.width="135px";const i=document.createElement("input");i.setAttribute("data-action","bgColor"),i.type="color",i.id=u.BG_COLOR_PICKER_ID,i.style.width="100%",i.style.height="32px",i.style.border="1px solid #000000ff",i.style.borderRadius="4px",i.style.cursor="pointer",i.style.marginBottom="8px",i.value="#ffffff",n.appendChild(i);const o=document.createElement("button");o.id=u.BG_COLOR_RESET_ID,o.type="button",o.textContent="Reset",o.style.display="block",o.style.width="100%",o.style.padding="6px 12px",o.style.fontSize="12px",o.style.border="1px solid #d1d1d1",o.style.borderRadius="4px",o.style.backgroundColor="#f8f8f8",o.style.cursor="pointer",o.style.transition="background-color 0.2s",o.onmouseenter=()=>o.style.backgroundColor="#e8e8e8",o.onmouseleave=()=>o.style.backgroundColor="#f8f8f8",n.appendChild(o),t.appendChild(n),a.appendChild(t)}else if("getHtmlContent"===t){const t=document.createElement("button");t.id=u.GET_HTML_BUTTON_ID,t.type="button",t.textContent="Get HTML",t.dataset.tooltip=h.getHtmlContent,a.appendChild(t)}else if("loadHtmlContent"===t){const t=document.createElement("select");t.id=u.LOAD_HTML_BUTTON_ID,t.dataset.action="loadHtmlContent",t.dataset.tooltip=h.loadHtmlContent,t.style.cursor="pointer",t.style.padding="4px 8px",t.style.border="1px solid #ccc",t.style.borderRadius="4px",t.style.backgroundColor="#f9f9f9",t.style.fontSize="13px",t.style.outline="none",t.style.color="#333",t.style.height="28px",t.addEventListener("mouseenter",()=>{t.style.backgroundColor="#eaeaea"}),t.addEventListener("mouseleave",()=>{t.style.backgroundColor="#f9f9f9"});const n=document.createElement("option");n.value="",n.textContent="Templates...",n.disabled=!0,n.selected=!0,t.appendChild(n);[...[{name:"Default Test",html:u.TEST_HTML_CODE},{name:"Blog Post",html:u.TEST_BLOG_POST_HTML_CODE},{name:"Newsletter",html:u.TEST_NEWSLATER_HTML_CODE},{name:"Resume",html:u.TEST_RESUME_HTML_CODE},{name:"Email",html:u.TEST_EMAIL_HTML_CODE},{name:"Meeting Notes",html:u.TEST_MEETING_HTML_CODE}],...e.templates||[]].forEach((e,n)=>{const i=document.createElement("option");i.value=n.toString(),i.dataset.html=e.html,i.textContent=e.name,t.appendChild(i)}),a.appendChild(t)}else if(p.map(t=>t.feature).includes(t)){const e=p.find(e=>e.feature===t),n=document.createElement("button");n.id=t,n.dataset.action=t,n.innerHTML=(null==e?void 0:e.icon)||"",n.dataset.tooltip=h[t]||t,a.appendChild(n)}else{const e=document.createElement("button");e.dataset.action=t,e.innerHTML=c[t]||t,e.id=t,e.dataset.tooltip=h[t]||t.split("_").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" "),a.appendChild(e)}});const C=document.createElement("div");C.id=u.HYPERLINK_CONTAINER_ID,C.style.display="none";const I=document.createElement("input");I.type="text",I.id=u.HYPERLINK_INPUT_ID,I.placeholder=u.HYPERLINK_PLACEHOLDER;const v=document.createElement("button");v.id=u.HYPERLINK_APPLY_BTN_ID,v.textContent="Link";const E=document.createElement("button");E.id=u.HYPERLINK_CANCEL_BTN_ID,E.textContent="Unlink",C.appendChild(I),C.appendChild(v),C.appendChild(E),a.appendChild(C);const x=document.createElement("div");x.id=u.VIEW_HYPERLINK_CONTAINER_ID,x.style.display="none";const w=document.createElement("span");w.id=u.VIEW_HYPERLINK_LABEL_ID,w.innerHTML="Visit URL : ";const S=document.createElement("a");return S.id=u.VIEW_HYPERLINK_ANCHOR_ID,S.href="",S.target="_blank",x.appendChild(w),x.appendChild(S),a.appendChild(x),{mainEditorId:n,toolbarId:i,popupToolbarId:o}}class C{constructor(t){this.htmlString=t,this.doc=(new DOMParser).parseFromString(t,"text/html")}parse(){const t=this.doc.body.children;let e=[];return Array.from(t).forEach((t,n)=>{const i=this.parseElement(t);console.log(t,"element parse",n,i),e.push(i)}),console.log(e,"element--jsondata"),e}parseElement(t){const e=t.getAttribute("data-id")||`data-id-${Date.now()}-${Math.floor(1e3*Math.random())}`,n=t.className||"paragraph-block",i=t.style.textAlign||"left";let o=null,s=null;"UL"===t.tagName?o="ul":"OL"===t.tagName&&(o="ol",s=parseInt(t.getAttribute("start")||"1",10));let l=[];return o?this.parseListItems(t,l):this.parseParagraphText(t,l),Object.assign(Object.assign(Object.assign({dataId:e,class:n,alignment:i,pieces:l},o?{listType:o}:{}),null!==s?{listStart:s}:{}),{})}parseListItems(t,e){t.querySelectorAll("li").forEach(t=>{const i=this.extractTextAttributes(t);i&&e.push(new n(i.text,i.attributes))})}parseParagraphText(t,e){const i=t.querySelectorAll("span"),o=new Map;i.forEach(t=>{const e=this.extractTextAttributes(t);if(console.log(e,"piece parseParagraphText span",t.textContent,t.style.color),e){const t=o.get(e.text);t?(t.attributes.bold=t.attributes.bold||e.attributes.bold,t.attributes.italic=t.attributes.italic||e.attributes.italic,t.attributes.underline=t.attributes.underline||e.attributes.underline,t.attributes.fontFamily=e.attributes.fontFamily||t.attributes.fontFamily,t.attributes.fontSize=e.attributes.fontSize||t.attributes.fontSize,t.attributes.fontColor=e.attributes.fontColor||t.attributes.fontColor,t.attributes.bgColor=e.attributes.bgColor||t.attributes.bgColor):o.set(e.text,Object.assign({},e))}}),o.forEach(t=>{e.push(new n(t.text,t.attributes))}),console.log(e,"pieces--parseParagraphText (merged)")}extractTextAttributes(t){var e;const n=t.textContent||"";return n?(console.log("extractTextAttributes node",t,t.style.color),{text:n,attributes:{bold:null!==t.querySelector("b, strong"),italic:null!==t.querySelector("i, em"),underline:null!==t.querySelector("u"),undo:!1,redo:!1,fontFamily:t.style.fontFamily||"Arial",fontSize:t.style.fontSize||"12px",hyperlink:!!t.querySelector("a")&&(null===(e=t.querySelector("a"))||void 0===e?void 0:e.getAttribute("href")),fontColor:t.style.color,bgColor:t.style.backgroundColor}}):null}rgbToHex(t,e=!1){const n=t.match(/\d+/g);if(!n||n.length<3)return null;const i=n.map(t=>{const e=parseInt(t);return e<0||e>255?"00":e.toString(16).padStart(2,"0")}).join("");return e||"000000"!==i?`#${i}`:null}}class I{constructor(t,e){this.editor=t,this.document=e,this.isImageHighlighted=!1,this.highLightedImageDataId="",this.currentCursorLocation=0,this.isCrossIconVisible=!1}setEditorView(t){this.editorView=t}insertImage(){const t=document.createElement("input");t.type="file",t.accept="image/*",t.click(),t.onchange=()=>{const e=t.files?t.files[0]:null;if(e){const t=new FileReader;t.onload=t=>{var e;const n=null===(e=t.target)||void 0===e?void 0:e.result;this.insertImageAtCursor(n)},t.readAsDataURL(e)}}}insertImageAtCursor(t){if(!t)return;const[e,n]=l(this.editorView);n>e&&this.document.deleteRange(e,n,this.document.selectedBlockId),this.insertImageAtPosition(t,e,this.document.selectedBlockId)}setCursorPostion(t,e){if("number"!=typeof t||!e)return;const n=document.querySelector(`[data-id="${e}"]`);n&&("function"==typeof n.focus&&n.focus(),setTimeout(()=>{const e=document.createRange(),i=window.getSelection();if(n.firstChild)e.setStart(n.firstChild,t);else{const t=document.createTextNode("");n.appendChild(t),e.setStart(t,0)}e.collapse(!0),null==i||i.removeAllRanges(),null==i||i.addRange(e)},0))}insertImageAtPosition(t,e,i){if(!t||"number"!=typeof e||!this.editorView)return;console.log(t,e,i,"vicky insertImageAtPosition",this.document.blocks);const o=`data-id-${Date.now()}-${1e3*Math.random()}`,s=`data-id-${Date.now()}-${1e3*Math.random()}`,l=`data-id-${Date.now()}-${1e3*Math.random()}`,r={dataId:o,class:u.PARAGRAPH_BLOCK_CLASS,pieces:[new n(" ")],type:"image",image:t},a={dataId:s,class:u.PARAGRAPH_BLOCK_CLASS,pieces:[new n(" ")],type:"text"};let d=this.document.selectedBlockId;const c=this.document.blocks.findIndex(t=>t.dataId===this.document.selectedBlockId);let h=[];const{remainingText:p,piece:g}=function(t,e){const n=window.getSelection();if(!n||0===n.rangeCount)return{remainingText:"",piece:null};const i=n.getRangeAt(0).startContainer;let o="";const s=e.blocks.filter(e=>{if(e.dataId===t)return e});if(!s[0]||!s[0].pieces)return{remainingText:"",piece:null};const l=document.querySelector(`[data-id="${t}"]`),r=e.getCursorOffsetInParent(`[data-id="${t}"]`);let a=[],d=0;if(s[0].pieces.forEach((t,e)=>{o+=t.text,(null==r?void 0:r.innerText)===t.text&&(d=e,a.push(t))}),s[0].pieces.length>1&&s[0].pieces.forEach((t,e)=>{d0){const t=p.split(" ");let e=[];""!==t[0]||void 0!==t[1]?1===g.length?e=[new n(m,g[0].attributes)]:(e.push(new n(" "+t[0]+" ",g[0].attributes)),g.length>=2&&g.forEach((t,n)=>{0!==n&&e.push(t)})):e=[new n(" ")],console.log(this.document.selectedBlockId,"uniqueId3 extractTextFromDataId-vicky",l),f=function(t,e,n){const i=t.findIndex(t=>t.dataId===e);return-1===i?(console.error(`Block with dataId "${e}" not found.`),t):[...t.slice(0,i+1),n,...t.slice(i+1)]}(this.document.blocks,this.document.selectedBlockId||"",{dataId:l,class:u.PARAGRAPH_BLOCK_CLASS,pieces:e,type:"text"})}this.document.blocks=f,this.document.deleteRange(this.currentCursorLocation,this.currentCursorLocation+p.length,this.document.selectedBlockId,this.document.currentOffset),this.document.blocks.length>c+1?this.document.blocks.forEach((t,e)=>{h.push(t),e===c?h.push(r):d===this.document.selectedBlockId&&(d=t.dataId)}):(h=[...this.document.blocks,r,a],d=a.dataId),this.document.blocks=h,this.editorView.render(),this.document.selectedBlockId=d;const b=document.querySelector(`[data-id="${d}"]`);b.focus(),setTimeout(()=>{const t=document.createRange(),e=window.getSelection();if(b.firstChild)t.setStart(b.firstChild,1);else{const e=document.createTextNode("");b.appendChild(e),t.setStart(e,0)}t.collapse(!0),null==e||e.removeAllRanges(),null==e||e.addRange(t)},0)}createImageFragment(t,e){if(!t||!e)return document.createDocumentFragment();const n=document.createDocumentFragment(),i=document.createElement("img");i.src=t,i.style.maxWidth="30%",i.setAttribute("contenteditable","false"),n.appendChild(i);const o=document.createElement("span");return o.setAttribute("contenteditable","false"),o.appendChild(n),i.addEventListener("click",()=>this.addStyleToImage(e)),o}addStyleToImage(t){if(t&&!this.isCrossIconVisible){const e=document.querySelector(`[data-id="${t}"]`),n=null==e?void 0:e.querySelector("span");n&&(n.style.position="relative");const i=null==e?void 0:e.querySelector("img");i&&(i.style.border="2px solid blue");const o=document.createElement("div");o.className=u.IMAGE_CROSS_CLASS,o.innerHTML="x",Object.assign(o.style,{position:"absolute",top:"0",left:"50%",transform:"translate(-50%, 0)",background:"#fff",borderRadius:"50%",width:"30px",height:"30px",display:"flex",alignItems:"center",justifyContent:"center",cursor:"pointer",border:"3px solid blue",zIndex:"999"}),o.addEventListener("mouseover",()=>o.style.border="3px solid black"),o.addEventListener("mouseout",()=>o.style.border="3px solid blue"),o.addEventListener("click",t=>{t.stopPropagation(),this.deleteImage()}),null==n||n.appendChild(o),this.isImageHighlighted=!0,this.highLightedImageDataId=t,this.isCrossIconVisible=!0}}clearImageStyling(){if(!this.highLightedImageDataId)return;const t=document.querySelector(`[data-id="${this.highLightedImageDataId}"]`);if(t){const e=t.querySelector("span");null==e||e.removeAttribute("style");const n=null==e?void 0:e.querySelector("img");n&&n.removeAttribute("style");const i=null==e?void 0:e.querySelector(`.${u.IMAGE_CROSS_CLASS}`);null==i||i.remove(),this.highLightedImageDataId=""}this.isCrossIconVisible=!1}deleteImage(){this.highLightedImageDataId&&(this.document.blocks=this.document.blocks.filter(t=>t.dataId!==this.highLightedImageDataId),this.highLightedImageDataId="",this.isImageHighlighted=!1,this.clearImageStyling(),this.document.emit("documentChanged",this))}}class v{constructor(t,e){this.snapshotUndoStack=[],this.snapshotRedoStack=[],this.maxSnapshots=5e3,this.document=t,this.editorView=e}createSnapshot(){const[t,e]=l(this.editorView);return{blocks:JSON.parse(JSON.stringify(this.document.blocks)),dataIds:[...this.document.dataIds],selectedBlockId:this.document.selectedBlockId,currentOffset:this.document.currentOffset,selection:this.getCurrentSelection(),cursorPosition:t}}getCurrentSelection(){const t=o(this.document.editorView.container);return t?{start:t.start,end:t.end}:{start:0,end:0}}saveUndoSnapshot(){const t=this.createSnapshot();console.log("Saving snapshot:",t.cursorPosition,"Stack length:",this.snapshotUndoStack.length),this.snapshotUndoStack.push(t),this.snapshotUndoStack.length>this.maxSnapshots&&this.snapshotUndoStack.shift(),this.snapshotRedoStack=[]}restoreSnapshot(t){this.document.blocks=t.blocks,this.document.dataIds=t.dataIds,this.document._selectedBlockId=t.selectedBlockId,this.document.currentOffset=t.currentOffset;for(let t of this.document.blocks)t.pieces&&Array.isArray(t.pieces)&&(t.pieces=t.pieces.map(t=>new n(t.text,t.attributes)));this.document.emit("documentChanged",this.document),setTimeout(()=>{this.document.setCursorPosition(t.cursorPosition||0)},0)}undo(){if(console.log("UNDO - Undo stack length:",this.snapshotUndoStack.length),console.log("UNDO - Redo stack length:",this.snapshotRedoStack.length),0===this.snapshotUndoStack.length)return;const t=this.createSnapshot();this.snapshotRedoStack.push(t),this.snapshotRedoStack.length>this.maxSnapshots&&this.snapshotRedoStack.shift();const e=this.snapshotUndoStack.pop();e&&(console.log("UNDO - Restoring cursor position:",e.cursorPosition),this.restoreSnapshot(e))}redo(){if(0===this.snapshotRedoStack.length)return;const t=this.createSnapshot();this.snapshotUndoStack.push(t),this.snapshotUndoStack.length>this.maxSnapshots&&this.snapshotUndoStack.shift();const e=this.snapshotRedoStack.pop();e&&this.restoreSnapshot(e)}}class E extends e{constructor(t){super(),this.container=t,this.setupButtons()}setupButtons(){this.container.addEventListener("mousedown",t=>{t.preventDefault()}),this.container.addEventListener("click",t=>{const e=t.target.closest("button");if(e){const t=e.getAttribute("data-action");t&&this.emit("popupAction",t)}})}show(t){const e=t.getRangeAt(0).getBoundingClientRect();if(0===e.width&&0===e.height)return void this.hide();this.container.style.display="flex";const n=this.container.offsetWidth,i=this.container.offsetHeight;let o=e.top+window.scrollY-i-8,s=e.left+window.scrollX+e.width/2-n/2;o{const n=e.getAttribute("data-action");let i=!1;"bold"===n&&t.bold&&(i=!0),"italic"===n&&t.italic&&(i=!0),"underline"===n&&t.underline&&(i=!0),"strikethrough"===n&&t.strikethrough&&(i=!0),"hyperlink"===n&&t.hyperlink&&(i=!0),e.classList.toggle("active",i)})}}class x{constructor(){this.linkElement=null,this.createPopup()}setCallbacks(t,e){this.onOpenClick=t,this.onUnlinkClick=e}createPopup(){this.popup=document.createElement("div"),this.popup.className="link-popup",this.popup.style.cssText="\n position: absolute;\n background: #000;\n border-radius: 4px;\n padding: 2px;\n box-shadow: 0 1px 4px rgba(0,0,0,0.5);\n z-index: 1000;\n display: none;\n ";const t=this.createButton("Open","🔗"),e=this.createButton("Unlink","✕");t.addEventListener("click",()=>this.handleOpenClick()),e.addEventListener("click",()=>this.handleUnlinkClick()),this.popup.appendChild(t),this.popup.appendChild(e),document.body.appendChild(this.popup)}createButton(t,e){const n=document.createElement("button");return n.innerHTML=`${e}`,n.title=t,n.style.cssText="\n background: transparent;\n color: white;\n border: none;\n padding: 4px;\n margin: 0 1px;\n border-radius: 2px;\n cursor: pointer;\n font-size: 16px;\n transition: background 0.1s;\n width: 24px;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n ",n.addEventListener("mouseenter",()=>{n.style.background="#333"}),n.addEventListener("mouseleave",()=>{n.style.background="transparent"}),n}handleOpenClick(){this.linkElement&&this.onOpenClick&&this.onOpenClick(this.linkElement.href)}handleUnlinkClick(){this.onUnlinkClick&&this.linkElement&&this.onUnlinkClick(this.linkElement)}show(t,e,n){this.linkElement=t;const i=t.getBoundingClientRect();this.popup.style.left=`${i.left+window.scrollX}px`,this.popup.style.top=`${i.bottom+window.scrollY+5}px`,this.popup.style.display="flex",this.popup.style.opacity="0",this.popup.style.transform="translateY(-2px)",requestAnimationFrame(()=>{this.popup.style.transition="opacity 0.1s ease-in-out, transform 0.1s ease-in-out",this.popup.style.opacity="1",this.popup.style.transform="translateY(0)"})}hide(){"none"!==this.popup.style.display&&(this.popup.style.transition="opacity 0.1s ease-in-out, transform 0.1s ease-in-out",this.popup.style.opacity="0",this.popup.style.transform="translateY(-2px)",setTimeout(()=>{this.popup.style.display="none",this.popup.style.transition=""},100))}isPopup(t){return this.popup.contains(t)}isVisible(){return"none"!==this.popup.style.display}}class w{constructor(t,e,n,i){this.isRecording=!1,this.silenceTimer=null,this.document=t,this.editorView=e,this.onStateChange=n,this.insertText=i;const o=window.SpeechRecognition||window.webkitSpeechRecognition;o?(this.recognition=new o,this.recognition.continuous=!0,this.recognition.interimResults=!1,this.recognition.onresult=t=>{const e=t.results[t.results.length-1];if(e.isFinal){const t=e[0].transcript+" ";this.insertText(t)}},this.recognition.onerror=t=>{console.error("Speech recognition error:",t.error),"no-speech"!==t.error&&this.stopRecording()},this.recognition.onend=()=>{this.stopRecording()}):console.warn("Speech Recognition API not supported in this browser.")}toggleRecording(){this.isRecording?this.stopRecording():this.startRecording()}startRecording(){if(this.recognition)try{this.recognition.start(),this.isRecording=!0,this.onStateChange(!0)}catch(t){console.error("Failed to start speech recognition:",t)}}stopRecording(){if(this.recognition&&this.isRecording){try{this.recognition.stop()}catch(t){console.warn("Some problem occur during the stop recording . . . ",t)}this.isRecording=!1,this.onStateChange(!1),this.silenceTimer&&(clearTimeout(this.silenceTimer),this.silenceTimer=null)}}}const S=[{label:"Smileys & People",items:[{char:"😀",name:"grinning face",shortcode:":grinning:"},{char:"😃",name:"big eyes smile",shortcode:":smiley:"},{char:"😄",name:"smiling eyes grin",shortcode:":smile:"},{char:"😁",name:"beaming grin",shortcode:":grin:"},{char:"😆",name:"squinting laugh",shortcode:":laughing:"},{char:"😅",name:"sweat smile",shortcode:":sweat_smile:"},{char:"🤣",name:"rolling floor laughing",shortcode:":rofl:"},{char:"😂",name:"tears of joy",shortcode:":joy:"},{char:"🙂",name:"slightly smiling",shortcode:":slightly_smiling_face:"},{char:"😊",name:"smiling eyes blush",shortcode:":blush:"}]}],T="recent_emojies";class A{constructor(){this.isOpen=!1,this.popup=this.buildPopup(),this.gridArea=this.popup.querySelector(".emoji_grid"),this.searchInput=this.popup.querySelector(".emoji_serch"),document.body.appendChild(this.popup),document.addEventListener("mousedown",t=>{if(this.isOpen&&!this.popup.contains(t.target)){t.target.closest('[data-action="emoji"]')||this.close()}})}onSelect(t){this.onSelectCallback=t}open(t){const e=t.getBoundingClientRect();let n=e.left+window.scrollX;n+320>window.innerWidth-8&&(n=window.innerWidth-320-8);const i=e.bottom+window.scrollY+4;this.popup.style.left=`${n}px`,this.popup.style.top=`${i}px`,this.popup.style.display="flex",this.isOpen=!0,this.searchInput.value="",this.renderGrid("")}close(){this.popup.style.display="none",this.isOpen=!1}getIsOpen(){return this.isOpen}buildPopup(){const t=document.createElement("div");t.style.cssText="\n position: absolute;\n display: none;\n flex-direction: column;\n width: 320px;\n max-height: 380px;\n background: #ffffff;\n border: 1px solid #dddddd;\n border-radius: 10px;\n box-shadow: 0 6px 24px rgba(0,0,0,0.14);\n z-index: 9999;\n overflow: hidden;\n font-family: system-ui, -apple-system, sans-serif;\n ";const e=document.createElement("div");e.style.cssText="\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 10px 12px;\n border-bottom: 1px solid #f0f0f0;\n background: #fafafa;\n ";const n=document.createElement("input");n.type="text",n.placeholder="🔍 Search emojis or :shortcode:",n.className="emoji_serch",n.style.cssText="\n flex: 1;\n padding: 6px 10px;\n border: 1px solid #ccc;\n border-radius: 6px;\n font-size: 13px;\n outline: none;\n background: #fff;\n ",n.addEventListener("input",()=>this.renderGrid(n.value.trim())),e.appendChild(n);const i=document.createElement("div");return i.className="emoji_grid",i.style.cssText="\n flex: 1;\n overflow-y: auto;\n padding: 10px 12px 12px;\n ",t.appendChild(e),t.appendChild(i),t}getRecentEmojis(){try{const t=localStorage.getItem(T);return t?JSON.parse(t):[]}catch(t){return[]}}saveRecentEmoji(t){const e=this.getRecentEmojis().filter(e=>e.char!==t.char);e.unshift(t),e.length>24&&(e.length=24);try{localStorage.setItem(T,JSON.stringify(e))}catch(t){console.error("Problem occur in saving emojies",t)}}resolveChar(t){return t.char}renderGrid(t){this.gridArea.innerHTML="";const e=t.toLowerCase().replace(/^:/,"").replace(/:$/,""),n=(t,e)=>{if(!e.length)return;const n=document.createElement("div");n.style.marginBottom="12px";const i=document.createElement("div");i.textContent=t,i.style.cssText="\n font-size: 11px;\n font-weight: 600;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n color: #999;\n margin-bottom: 6px;\n ",n.appendChild(i);const o=document.createElement("div");o.style.cssText="\n display: grid;\n grid-template-columns: repeat(8, 1fr);\n gap: 2px;\n ",e.forEach(t=>{const e=this.resolveChar(t),n=document.createElement("button");n.textContent=e,n.title=`${t.name} ${t.shortcode}`,n.style.cssText="\n font-size: 20px;\n background: transparent;\n border: none;\n cursor: pointer;\n border-radius: 5px;\n padding: 4px;\n line-height: 1.2;\n transition: background 0.1s;\n aspect-ratio: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n ",n.addEventListener("mouseenter",()=>n.style.background="#f0f0f0"),n.addEventListener("mouseleave",()=>n.style.background="transparent"),n.addEventListener("mousedown",n=>{var i;n.preventDefault(),this.saveRecentEmoji(t),null===(i=this.onSelectCallback)||void 0===i||i.call(this,e)}),o.appendChild(n)}),n.appendChild(o),this.gridArea.appendChild(n)};if(e){const t=[];S.forEach(n=>{n.items.forEach(n=>{(n.name.includes(e)||n.shortcode.includes(e))&&t.push(n)})}),n(`Results for "${e}"`,t)}else{const t=this.getRecentEmojis();n("Recently Used",t),S.forEach(t=>n(t.label,t.items))}if(!this.gridArea.querySelector("button")){const t=document.createElement("div");t.textContent="No emojis found",t.style.cssText="text-align: center; color: #aaa; padding: 24px 0; font-size: 13px;",this.gridArea.appendChild(t)}}}class L extends e{constructor(t,e){var o,s,l,d,m,b,y,S,T,L,R,_,O;super(),this.savedSelection=null,this.debounceTimer=null;const{mainEditorId:B,toolbarId:H,popupToolbarId:N}=k(t,e);this.editorContainer=document.getElementById(B)||null,this.toolbarContainer=document.getElementById(H)||null;const P=document.getElementById(N)||null;if(!this.editorContainer||!this.toolbarContainer||!P)throw new Error("Editor element not found or incorrect element type.");this.document=new i,this.editorView=new c(this.editorContainer,this.document),this.toolbarView=new h(this.toolbarContainer),this.popupToolbarView=new E(P),this.linkPopupView=new x,this.hyperlinkHandler=new p(this.editorContainer,this.editorView,this.document),this.imageHandler=new I(this.editorContainer,this.document),this.undoRedoManager=new v(this.document,this.editorView),this.editorView.setImageHandler(this.imageHandler),this.imageHandler.setEditorView(this.editorView),this.document.setEditorView(this.editorView),this.document.setUndoRedoManager(this.undoRedoManager),this.hyperlinkHandler.setUndoRedoManager(this.undoRedoManager),this.linkPopupView.setCallbacks(t=>this.openLink(t),t=>this.unlinkText(t)),this.speechToTextHandler=new w(this.document,this.editorView,t=>{const e=document.getElementById("speechtotext");e&&(e.innerHTML=t?f.stop_microphone:f.start_microphone,e.dataset.tooltip=t?"stop":"start")},t=>{const[e,n]=this.getSelectionRange();n>e&&this.document.deleteRange(e,n,this.document.selectedBlockId,this.document.currentOffset);let i=e;this.document.insertAt(t,Object.assign({},this.currentAttributes),i,this.document.selectedBlockId,0,"","batch"),i+=t.length,this.setCursorPosition(i)});const D=document.getElementById("speechtotext");D&&(D.innerHTML="",D.insertAdjacentHTML("afterbegin",f.start_microphone),D.dataset.tooltip="start"),this.emojiPickerView=new A,this.emojiPickerView.onSelect(t=>{this.savedSelection&&this.setCursorPosition(this.savedSelection.start);const[e,n]=this.getSelectionRange();n>e&&this.document.deleteRange(e,n,this.document.selectedBlockId,this.document.currentOffset,!1),this.document.insertAt(t,Object.assign({},this.currentAttributes),e,this.document.selectedBlockId,0,"","batch");const i=e+t.length;this.savedSelection={start:i,end:i},this.setCursorPosition(i)}),this.currentAttributes={bold:!1,italic:!1,underline:!1,strikethrough:!1,undo:!1,redo:!1,hyperlink:!1},this.manualOverride=!1,this.lastPiece=null,this.toolbarView.on("toolbarAction",(t,e=[])=>this.handleToolbarAction(t,e)),this.popupToolbarView.on("popupAction",t=>this.handleToolbarAction(t)),this.document.on("documentChanged",()=>{if(0===this.document.blocks.length||1===this.document.blocks.length&&this.document.blocks[0].pieces.every(t=>""===t.text.trim()||"​"===t.text)){const t=document.getElementById("loadHtmlButton");t&&(t.selectedIndex=0)}this.editorView.render()}),this.document.on("documentChanged",()=>{var t;const e=this.document.getHtmlContent();this.emit("contentChange",{html:e,text:(null===(t=this.editorContainer)||void 0===t?void 0:t.textContent)||""})}),this.editorContainer.addEventListener("keydown",t=>{this.syncCurrentAttributesWithCursor(),this.handleKeydown(t)}),this.editorContainer.addEventListener("keyup",()=>this.syncCurrentAttributesWithCursor()),this.editorContainer.addEventListener("blur",()=>{this.hyperlinkHandler.hideHyperlinkViewButton()}),document.addEventListener("mouseup",()=>{this.syncCurrentAttributesWithCursor();const t=this.document.getAllSelectedDataIds();console.log(t,"dataId lntgerr")}),document.addEventListener("selectionchange",()=>{const t=window.getSelection();t&&!t.isCollapsed||(this.document.dataIds=[],this.document.selectAll=!1)}),null===(o=document.getElementById("fontColor"))||void 0===o||o.addEventListener("click",t=>{t.stopPropagation();const e=document.getElementById("colorWrapper"),n=document.getElementById("fontColorPicker");if(!e||!n)return;const i="block"===e.style.display;e.style.display=i?"none":"block"}),null===(s=document.getElementById("fontColorPicker"))||void 0===s||s.addEventListener("input",t=>{const e=t.target.value,[n,i]=this.getSelectionRange(),o=document.getElementById("fontColorIndicator");o&&(o.style.backgroundColor=e),this.document.dataIds.length>1?this.document.blocks.forEach(t=>{if(this.document.dataIds.includes(t.dataId)){this.document.selectedBlockId=t.dataId;let i=0;t.pieces.forEach(t=>{i+=t.text.length});let o=n-i;this.document.applyFontColor(o,i,e)}}):(this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.document.applyFontColor(n,i,e)},300))}),null===(l=document.getElementById("colorResetFont"))||void 0===l||l.addEventListener("click",()=>{const t=document.getElementById("fontColorPicker"),e=document.getElementById("fontColorIndicator");t&&(t.value="#000000",e&&(e.style.backgroundColor="#000000"),t.dispatchEvent(new Event("input")))}),document.addEventListener("click",t=>{var e;const n=t.target,i=document.getElementById("colorWrapper"),o=document.getElementById("colorBgWrapper"),s=document.getElementById("fontColor"),l=document.getElementById("bgColor");!i||n.closest("#colorWrapper")||n===s||(null==s?void 0:s.contains(n))||(i.style.display="none"),!o||n.closest("#colorBgWrapper")||n===l||(null==l?void 0:l.contains(n))||(o.style.display="none"),(null===(e=this.editorContainer)||void 0===e?void 0:e.contains(n))||n.closest(".hyperlink-popup")||this.hyperlinkHandler.hideHyperlinkViewButton()}),null===(d=document.getElementById("bgColor"))||void 0===d||d.addEventListener("click",t=>{t.stopPropagation();const e=document.getElementById("colorBgWrapper"),n=document.getElementById("bgColorPicker");if(!e||!n)return;const i="block"===e.style.display;e.style.display=i?"none":"block"}),null===(m=document.getElementById("bgColorPicker"))||void 0===m||m.addEventListener("input",t=>{const e=t.target.value,[n,i]=this.getSelectionRange(),o=document.getElementById("bgColorIndicator");o&&(o.style.backgroundColor=e),this.document.dataIds.length>1?this.document.blocks.forEach(t=>{if(this.document.dataIds.includes(t.dataId)){this.document.selectedBlockId=t.dataId;let i=0;t.pieces.forEach(t=>{i+=t.text.length});let o=n-i;this.document.applyBgColor(o,i,e)}}):(this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.document.applyBgColor(n,i,e)},300))}),null===(b=document.getElementById("colorResetBG"))||void 0===b||b.addEventListener("click",()=>{const t=document.getElementById("bgColorPicker"),e=document.getElementById("bgColorIndicator");t&&(t.value="#ffffff",e&&(e.style.backgroundColor="#ffffff"),t.dispatchEvent(new Event("input")))}),null===(y=document.getElementById("getHtmlButton"))||void 0===y||y.addEventListener("click",t=>{const e=this.document.getHtmlContent(!0);console.log("Editor HTML Content:",e),this.htmlToJsonParser=new C(e);const n=this.htmlToJsonParser.parse();console.log("htmltoJson",JSON.stringify(n,null,2),n),this.showAcknowledgement("HTML copied to clipboard",2e3)}),null===(S=document.getElementById("loadHtmlButton"))||void 0===S||S.addEventListener("change",t=>{this.undoRedoManager.saveUndoSnapshot();const e=t.target,n=e.options[e.selectedIndex].dataset.html||u.TEST_HTML_CODE;this.htmlToJsonParser=new C(n),console.log(this.htmlToJsonParser,"this.htmlToJsonParser");const i=this.htmlToJsonParser.parse();this.document.blocks=i,i.length>0&&(this.document.dataIds[0]=i[0].dataId,this.document.selectedBlockId=i[0].dataId),this.document.emit("documentChanged",this);const[o]=this.getSelectionRange();this.document.blocks.forEach(t=>{if(this.document.dataIds.includes(t.dataId)){this.document.selectedBlockId=t.dataId;let e=0;t.pieces.forEach(t=>{e+=t.text.length});let n=o-e;t.fontSize&&this.document.setFontSize(n,e,t.fontSize)}}),console.log("blocks",this.document.blocks,this.document.dataIds,this.document.currentOffset),console.log("htmltoJson",JSON.stringify(i,null,2),i)}),null===(T=document.getElementById("fontFamily"))||void 0===T||T.addEventListener("change",t=>{this.undoRedoManager.saveUndoSnapshot();const e=t.target.value,[n,i]=this.getSelectionRange();this.document.dataIds.length>1?this.document.blocks.forEach(t=>{if(this.document.dataIds.includes(t.dataId)){this.document.selectedBlockId=t.dataId;let i=0;t.pieces.forEach(t=>{i+=t.text.length});let o=n-i;this.document.setFontFamily(o,i,e)}}):this.document.setFontFamily(n,i,e)}),null===(L=document.getElementById("fontSize"))||void 0===L||L.addEventListener("change",t=>{this.undoRedoManager.saveUndoSnapshot();const e=t.target.value,[n,i]=this.getSelectionRange();this.document.dataIds.length>1?this.document.blocks.forEach(t=>{if(this.document.dataIds.includes(t.dataId)){this.document.selectedBlockId=t.dataId;let i=0;t.pieces.forEach(t=>{i+=t.text.length});let o=n-i;this.document.setFontSize(o,i,e)}}):this.document.setFontSize(n,i,e)}),null===(R=document.getElementById("alignLeft"))||void 0===R||R.addEventListener("click",()=>{console.log("alignment alignLeft",this.document.dataIds),this.document.dataIds.forEach(t=>this.document.setAlignment("left",t))}),null===(_=document.getElementById("alignCenter"))||void 0===_||_.addEventListener("click",()=>{console.log("alignment alignCenter",this.document.dataIds),this.document.dataIds.forEach(t=>this.document.setAlignment("center",t))}),null===(O=document.getElementById("alignRight"))||void 0===O||O.addEventListener("click",()=>{console.log("alignment alignRight",this.document.dataIds),this.document.dataIds.forEach(t=>this.document.setAlignment("right",t))}),this.editorContainer.addEventListener("keydown",t=>{if((t.ctrlKey||t.metaKey)&&!t.altKey){const e=t.key.toLowerCase();if(["b","i","u","h"].includes(e)){t.preventDefault();let n="b";switch(e){case"b":n="bold";break;case"i":n="italic";break;case"u":n="underline";break;case"h":n="hyperlink"}this.handleToolbarAction(n)}if("z"===e?(t.preventDefault(),this.undoRedoManager.undo()):"y"===e&&(t.preventDefault(),this.undoRedoManager.redo()),"a"===e){const t=this.document.handleCtrlASelection();this.document.selectAll=!0,console.log("Selected text is inside element with data-id:",t)}"l"===t.key?(t.preventDefault(),this.document.setAlignment("left",this.document.selectedBlockId)):"e"===t.key?(t.preventDefault(),this.document.setAlignment("center",this.document.selectedBlockId)):"r"===t.key&&(t.preventDefault(),this.document.setAlignment("right",this.document.selectedBlockId))}}),document.addEventListener("selectionchange",this.handleSelectionChange.bind(this)),this.editorContainer.addEventListener("click",t=>{const e=t.target;if("A"===e.tagName||e.closest("a")){t.preventDefault(),t.stopPropagation();const n="A"===e.tagName?e:e.closest("a");this.showLinkPopup(n,t.clientX,t.clientY)}else this.hideLinkPopup()}),document.addEventListener("click",t=>{this.linkPopupView.isPopup(t.target)||this.hideLinkPopup()}),this.document.emit("documentChanged",this.document),this.editorContainer.addEventListener("paste",t=>{var e,i;this.undoRedoManager.saveUndoSnapshot(),t.preventDefault();const o=null===(e=t.clipboardData)||void 0===e?void 0:e.getData("text/html"),[s,l]=this.getSelectionRange();l>s&&this.document.deleteRange(s,l,this.document.selectedBlockId,this.document.currentOffset);let d=[];if(o)d=g(o);else{const e=function(t){const e=[];let n,i=0;for(;null!==(n=r.exec(t));){const o=n.index;let s=n[0],l="";const r=s.match(/[.,!?;:)\]\}"']+$/);if(r&&(l=r[0],s=s.slice(0,-l.length)),a(t,o))continue;o>i&&e.push({text:t.substring(i,o),isUrl:!1});let d=s;d.startsWith("http")||(d="https://"+d),e.push({text:s,isUrl:!0,url:d}),l&&e.push({text:l,isUrl:!1}),i=o+n[0].length}return it.isUrl&&t.url?new n(t.text,Object.assign(Object.assign({},this.currentAttributes),{hyperlink:t.url})):new n(t.text,Object.assign({},this.currentAttributes)))}let c=s;for(const t of d)this.document.insertAt(t.text,Object.assign({},t.attributes),c,this.document.selectedBlockId,0,"","batch"),c+=t.text.length;this.setCursorPosition(c)}),this.editorContainer.addEventListener("dragover",t=>{t.preventDefault()}),this.editorContainer.addEventListener("drop",t=>{var e,i;t.preventDefault(),this.undoRedoManager.saveUndoSnapshot();const o=null===(e=t.dataTransfer)||void 0===e?void 0:e.getData("text/html"),[s,l]=this.getSelectionRange();l>s&&this.document.deleteRange(s,l,this.document.selectedBlockId,this.document.currentOffset);let r=[];if(o)r=g(o);else{const e=(null===(i=t.dataTransfer)||void 0===i?void 0:i.getData("text/plain"))||"";r=[new n(e,Object.assign({},this.currentAttributes))]}let a=s;for(const t of r)this.document.insertAt(t.text,Object.assign({},t.attributes),a,this.document.selectedBlockId,0,"","batch"),a+=t.text.length;this.setCursorPosition(a)})}getSelectionRange(){const t=o(this.editorView.container);return t?[t.start,t.end]:[0,0]}applyFontColor(t){const e=window.getSelection();if(!e||0===e.rangeCount)return;e.getRangeAt(0).toString()}handleToolbarAction(t,e=[]){const[n,i]=this.getSelectionRange();switch(t){case"orderedList":if(this.document.dataIds.length>1)this.document.toggleOrderedListForMultipleBlocks(this.document.dataIds);else{const t=this.document.selectedBlockId||this.document.dataIds[0];this.document.toggleOrderedList(t)}this.document.updateOrderedListNumbers();break;case"unorderedList":this.document.dataIds.forEach(t=>{this.document.toggleUnorderedList(t)});break;case"image":this.imageHandler.insertImage();break;case"speechtotext":this.speechToTextHandler.toggleRecording();break;case"emoji":this.savedSelection=o(this.editorView.container);const e=document.querySelector('[data-action="emoji"]');e.addEventListener("mousedown",t=>{t.preventDefault()}),e&&this.emojiPickerView.open(e);break;default:if(n1?this.document.blocks.forEach(t=>{if(this.document.dataIds.includes(t.dataId)){this.document.selectedBlockId=t.dataId;let e=0;t.pieces.forEach(t=>{e+=t.text.length});let i=n-e;this.document.toggleBoldRange(i,e)}}):this.document.toggleBoldRange(n,i);break;case"italic":this.document.dataIds.length>1?this.document.blocks.forEach(t=>{if(this.document.dataIds.includes(t.dataId)){this.document.selectedBlockId=t.dataId;let e=0;t.pieces.forEach(t=>{e+=t.text.length});let i=n-e;this.document.toggleItalicRange(i,e)}}):this.document.toggleItalicRange(n,i);break;case"underline":this.document.dataIds.length>1?this.document.blocks.forEach(t=>{if(this.document.dataIds.includes(t.dataId)){this.document.selectedBlockId=t.dataId;let e=0;t.pieces.forEach(t=>{e+=t.text.length});let i=n-e;this.document.toggleUnderlineRange(i,e)}}):this.document.toggleUnderlineRange(n,i);break;case"strikethrough":this.document.dataIds.length>1?this.document.blocks.forEach(t=>{if(this.document.dataIds.includes(t.dataId)){this.document.selectedBlockId=t.dataId;let e=0;t.pieces.forEach(t=>{e+=t.text.length});let i=n-e;this.document.toggleStrikethroughRange(i,e)}}):this.document.toggleStrikethroughRange(n,i);break;case"hyperlink":this.hyperlinkHandler.hanldeHyperlinkClick(n,i,this.document.currentOffset,this.document.selectedBlockId,this.document.blocks)}else this.currentAttributes[t]=!this.currentAttributes[t],this.manualOverride=!0}this.toolbarView.updateActiveStates(this.currentAttributes)}handleSelectionChange(){var t,e;const n=window.getSelection();if(!n||0===n.rangeCount||!(null===(t=this.editorContainer)||void 0===t?void 0:t.contains(n.anchorNode)))return this.hyperlinkHandler.hideHyperlinkViewButton(),void this.popupToolbarView.hide();const[i]=this.getSelectionRange();if(this.imageHandler.currentCursorLocation=i,n.isCollapsed?(this.document.dataIds=[],this.document.selectAll=!1,this.popupToolbarView.hide()):(this.document.getAllSelectedDataIds(),this.document.dataIds.length===this.document.blocks.length&&this.document.blocks.length>0&&(this.document.selectAll=!0),this.popupToolbarView.show(n)),!n||0===n.rangeCount)return;n&&!0===n.isCollapsed&&(this.document.dataIds=[],this.document.selectAll=!1);const o=n.getRangeAt(0),s=(null===(e=o.startContainer.parentElement)||void 0===e?void 0:e.closest("[data-id]"))||o.startContainer;s instanceof HTMLElement&&(this.document.selectedBlockId=s.getAttribute("data-id")||(o.startContainer instanceof HTMLElement?o.startContainer.getAttribute("data-id"):null)),this.syncCurrentAttributesWithCursor()}handleKeydown(t){var e,i;const[o,s]=this.getSelectionRange();if(this.imageHandler.currentCursorLocation=o,"Enter"===t.key){t.preventDefault(),this.undoRedoManager.saveUndoSnapshot();const i=`data-id-${Date.now()}`,l=this.document.blocks.findIndex(t=>t.dataId===this.document.selectedBlockId),r=this.document.blocks[l],a=(null===(e=null==r?void 0:r.pieces)||void 0===e?void 0:e.length)>0?r.pieces[r.pieces.length-1]:null,d=a?Object.assign({},a.attributes):{fontFamily:"Arial",fontSize:"16px",fontColor:"#000000",bgColor:"#ffffff",bold:!1,italic:!1,underline:!1,strikethrough:!1};if(r&&"image"===r.type)this.document.blocks.splice(l+1,0,{dataId:i,class:"paragraph-block",pieces:[new n("​",d)],type:"text"}),this.document.emit("documentChanged",this),this.imageHandler.setCursorPostion(1,i);else if(!r||"ol"!==r.listType&&"ul"!==r.listType&&"li"!==r.listType){const t=this.getCurrentCursorBlock(),e=null==t?void 0:t.toString();if(e&&r&&"text"===r.type){const t=o-this.document.currentOffset,s=[],l=[];let a=0;for(const e of r.pieces){const i=a+e.text.length;if(i<=t)s.push(e.clone());else if(a>=t)l.push(e.clone());else{const i=t-a,o=e.text.slice(0,i),r=e.text.slice(i);o&&s.push(new n(o,Object.assign({},e.attributes))),r&&l.push(new n(r,Object.assign({},e.attributes)))}a=i}r.pieces=s.length>0?s:[new n("​",d)];const c=l.length>0?l:[new n("​",d)],h=this.addBlockAfter(this.document.blocks,e,{dataId:i,class:"paragraph-block",pieces:c,type:"text"});this.document.blocks=h}else this.document.blocks.push({dataId:i,class:"paragraph-block",pieces:[new n("​",d)],type:"text"})}else{let t={dataId:i,class:"paragraph-block",pieces:[new n("​",d)],type:"text"},e="";if("ol"===r.listType?(t.listType="li",t.listStart=r.listStart+1,t.parentId=r.dataId,e=r.dataId):"li"===r.listType?(t.listType="li",t.listStart=r.listStart+1,t.parentId=r.parentId,e=r.parentId):"ul"===r.listType&&(t.listType="ul",t.parentId=r.parentId||r.dataId),this.document.blocks.splice(l+1,0,t),"ol"===r.listType||"li"===r.listType)for(let t=l+2;tt.dataId===this.imageHandler.highLightedImageDataId);return this.imageHandler.deleteImage(),void this.imageHandler.setCursorPostion(1,this.document.blocks[t-1].dataId)}const e=window.getSelection();console.log(e,"selection lntgerr");if((this.document.selectAll||this.document.dataIds.length===this.document.blocks.length&&this.document.dataIds.length>0||this.document.dataIds.length>1)&&!(null===(i=window.getSelection())||void 0===i?void 0:i.isCollapsed)){this.undoRedoManager.saveUndoSnapshot();const t=this.document.dataIds[0],e=this.document.blocks.findIndex(e=>e.dataId===t);this.document.deleteBlocks();let i=null,o=0;if(0===this.document.blocks.length){const t=`data-id-${Date.now()}`;this.document.blocks.push({dataId:t,class:"paragraph-block",pieces:[new n(" ")],type:"text"}),i=t,o=0,this.editorView.render()}else if(et+e.text.length,0)}return void this.setCursorPosition(o,i)}if(s>o){this.undoRedoManager.saveUndoSnapshot();const t=Math.min(this.document.currentOffset,o);this.document.deleteRange(o,s,this.document.selectedBlockId,t,!0),this.setCursorPosition(o-1);const e=this.document.blocks.findIndex(t=>t.dataId===this.document.selectedBlockId);console.log(e,"index lntgerr");if(null===document.querySelector(`[data-id="${this.document.selectedBlockId}"]`)){let t=0;console.log(t," listStart lntgerr");const e=this.document.blocks.map((e,n)=>(void 0===(null==e?void 0:e.listType)&&null===(null==e?void 0:e.listType)||("ol"===(null==e?void 0:e.listType)?(t=1,e.listStart=1):"li"===(null==e?void 0:e.listType)&&(t+=1,e.listStart=t)),e));console.log(e,"blocks lntgerr"),this.document.emit("documentChanged",this)}}else o===s&&o>0&&(this.document.deleteRange(o-1,o,this.document.selectedBlockId,this.document.currentOffset,!0),this.setCursorPosition(o-1))}else if(1!==t.key.length||t.ctrlKey||t.metaKey||t.altKey){if("Delete"===t.key){if(t.preventDefault(),o===s){if(this.undoRedoManager.saveUndoSnapshot(),s>o){const t=Math.min(this.document.currentOffset,o);this.document.deleteRange(o,s,this.document.selectedBlockId,t),this.setCursorPosition(o)}else if(s>o)return this.undoRedoManager.saveUndoSnapshot(),void this.document.deleteRange(o,s,this.document.selectedBlockId);const t=this.document.blocks.findIndex(t=>t.dataId===this.document.selectedBlockId);if(-1===t)return;const e=this.document.blocks[t].pieces.reduce((t,e)=>t+e.text.length,0);o-this.document.currentOffseto&&(this.undoRedoManager.saveUndoSnapshot(),this.document.deleteRange(o,s,this.document.selectedBlockId),this.setCursorPosition(o))}this.hyperlinkHandler.hideHyperlinkViewButton()}}else t.preventDefault(),s>o&&(this.undoRedoManager.saveUndoSnapshot(),this.document.deleteRange(o,s,this.document.selectedBlockId,this.document.currentOffset,!1)),console.log("insertat",t.key,this.currentAttributes,o,this.document.selectedBlockId,this.document.currentOffset,"","",!t.isTrusted||!1),this.document.insertAt(t.key,this.currentAttributes,o,this.document.selectedBlockId,this.document.currentOffset,"","",!t.isTrusted||!1),this.setCursorPosition(o+1)}extractTextFromDataId(t){const e=window.getSelection();if(console.log("selection::",e),!e||0===e.rangeCount)return{remainingText:"",piece:null};const n=e.getRangeAt(0).startContainer;let i="";console.log(0,"count lntgerr");const o=this.document.blocks.filter(e=>{if(e.dataId===t)return e}),s=document.querySelector(`[data-id="${t}"]`),l=this.document.getCursorOffsetInParent(`[data-id="${t}"]`);let r=[],a=0;if(o[0].pieces.forEach((t,e)=>{i+=t.text,(null==l?void 0:l.innerText)===t.text&&(a=e,r.push(t))}),o[0].pieces.length>1&&o[0].pieces.forEach((t,e)=>{at.dataId===e);if(-1===i)return console.error(`Block with dataId "${e}" not found.`),t;return[...t.slice(0,i+1),n,...t.slice(i+1)]}syncCurrentAttributesWithCursor(){var t;const[e,n]=this.getSelectionRange();console.log("log1",{start:e,end:n});const i=this.document.blocks.findIndex(t=>t.dataId===this.document.selectedBlockId);if("image"===(null===(t=this.document.blocks[i])||void 0===t?void 0:t.type)?this.imageHandler.addStyleToImage(this.document.selectedBlockId||""):this.imageHandler.isImageHighlighted&&this.imageHandler.clearImageStyling(),e===n){const t=this.document.findPieceAtOffset(e,this.document.selectedBlockId);t?(t!==this.lastPiece&&(this.manualOverride=!1,this.lastPiece=t),this.manualOverride||(this.currentAttributes={bold:t.attributes.bold,italic:t.attributes.italic,underline:t.attributes.underline,strikethrough:t.attributes.strikethrough||!1,hyperlink:t.attributes.hyperlink||!1,fontFamily:t.attributes.fontFamily,fontSize:t.attributes.fontSize,fontColor:t.attributes.fontColor,bgColor:t.attributes.bgColor},this.toolbarView.updateActiveStates(this.currentAttributes),this.popupToolbarView.updateActiveStates(this.currentAttributes)),this.hyperlinkHandler.hideHyperlinkViewButton()):(this.hyperlinkHandler.hideHyperlinkViewButton(),this.manualOverride||(this.currentAttributes={bold:!1,italic:!1,underline:!1,strikethrough:!1,hyperlink:!1},this.toolbarView.updateActiveStates(this.currentAttributes),this.popupToolbarView.updateActiveStates(this.currentAttributes)),this.lastPiece=null)}else{this.hyperlinkHandler.hideHyperlinkViewButton();const t=this.document.isRangeEntirelyAttribute(e,n,"bold"),i=this.document.isRangeEntirelyAttribute(e,n,"italic"),o=this.document.isRangeEntirelyAttribute(e,n,"underline"),s=this.document.isRangeEntirelyAttribute(e,n,"strikethrough");this.currentAttributes={bold:t,italic:i,underline:o,strikethrough:s,hyperlink:!1},this.toolbarView.updateActiveStates(this.currentAttributes),this.popupToolbarView.updateActiveStates(this.currentAttributes)}}setCursorPosition(t,e=""){if(""===e)this.editorView.container.focus();else{const t=document.querySelector('[data-id="'+e+'"]');t&&t.focus()}const n=window.getSelection();if(!n)return;const i=document.createRange();let o=0;const s=[this.editorView.container];let l;for(;l=s.pop();)if(3===l.nodeType){const e=l,n=o+e.length;if(t>=o&&t<=n){i.setStart(e,t-o),i.collapse(!0);break}o=n}else if("BR"===l.tagName){if(t===o){i.setStartBefore(l),i.collapse(!0);break}o++}else{const t=l;let e=t.childNodes.length;for(;e--;)s.push(t.childNodes[e])}n.removeAllRanges(),n.addRange(i)}showAcknowledgement(t,e=2e3){const n=document.getElementById(u.TOAST_ID);n&&n.remove();const i=document.createElement("div");i.id=u.TOAST_ID,i.className="ti-toast",i.textContent=t||u.TOAST_DEFAULT_MESSAGE,document.body.appendChild(i),i.offsetHeight,i.classList.add(u.TOAST_SHOW_CLASS),setTimeout(()=>{i.classList.remove(u.TOAST_SHOW_CLASS),setTimeout(()=>i.remove(),200)},e||u.TOAST_DEFAULT_DURATION_MS)}showLinkPopup(t,e,n){this.linkPopupView.show(t,e,n)}hideLinkPopup(){this.linkPopupView.hide()}openLink(t){window.open(t,"_blank"),this.hideLinkPopup()}unlinkText(t){this.undoRedoManager.saveUndoSnapshot();const e=t.textContent||"",n=(this.editorView.container.textContent||"").indexOf(e);-1!==n&&(this.document.formatAttribute(n,n+e.length,"hyperlink",!1),this.editorView.render()),this.hideLinkPopup()}onContentChange(t){this.on("contentChange",t)}getContent(){return this.document.getHtmlContent()||""}getTextContent(){var t;return(null===(t=this.editorContainer)||void 0===t?void 0:t.textContent)||""}}window.TextIgniter=L,t.TextIgniter=L}); diff --git a/packages/core/index.html b/packages/core/index.html index 75b4b76..be9b8c8 100644 --- a/packages/core/index.html +++ b/packages/core/index.html @@ -50,7 +50,8 @@

Real-time Content Preview:

'bgColor', 'getHtmlContent', 'loadHtmlContent', - 'speechtotext' + 'speechtotext', + 'emoji' // "subscript", // "superscript", // "insert_table", diff --git a/packages/core/src/TextIgniter.ts b/packages/core/src/TextIgniter.ts index 12e8953..8bcd172 100644 --- a/packages/core/src/TextIgniter.ts +++ b/packages/core/src/TextIgniter.ts @@ -18,6 +18,7 @@ import { detectUrlsInText } from './utils/urlDetector'; import EventEmitter from './utils/events'; import { SpeechToTextHandler } from './handlers/speechToText'; import { icons } from './assets/icons'; +import EmojiPickerView from './view/emojiPickerView'; // Link functionality imports export interface CurrentAttributeDTO { @@ -52,6 +53,7 @@ class TextIgniter extends EventEmitter { savedSelection: { start: number; end: number } | null = null; debounceTimer: NodeJS.Timeout | null = null; undoRedoManager: UndoRedoManager; + emojiPickerView: EmojiPickerView; constructor(editorId: string, config: EditorConfig) { super(); @@ -138,6 +140,42 @@ class TextIgniter extends EventEmitter { btn.insertAdjacentHTML('afterbegin', icons.start_microphone); btn.dataset.tooltip = 'start'; } + + this.emojiPickerView = new EmojiPickerView(); + this.emojiPickerView.onSelect((char: string) => { + if (this.savedSelection) { + this.setCursorPosition(this.savedSelection.start); + } + + const [start, end] = this.getSelectionRange(); + + if (end > start) { + this.document.deleteRange( + start, + end, + this.document.selectedBlockId, + this.document.currentOffset, + false + ); + } + + this.document.insertAt( + char, + { ...this.currentAttributes }, + start, + this.document.selectedBlockId, + 0, + '', + 'batch' + ); + + const newPos = start + char.length; + + this.savedSelection = { start: newPos, end: newPos }; + + this.setCursorPosition(newPos); + }); + this.currentAttributes = { bold: false, italic: false, @@ -745,6 +783,19 @@ class TextIgniter extends EventEmitter { case 'speechtotext': this.speechToTextHandler.toggleRecording(); break; + case 'emoji': + this.savedSelection = saveSelection(this.editorView.container); + + const emojiBtn = document.querySelector( + '[data-action="emoji"]' + ) as HTMLElement; + emojiBtn.addEventListener('mousedown', e => { + e.preventDefault(); + }); + if (emojiBtn) { + this.emojiPickerView.open(emojiBtn); + } + break; default: if (start < end) { this.undoRedoManager.saveUndoSnapshot(); diff --git a/packages/core/src/assets/icons.ts b/packages/core/src/assets/icons.ts index ff4971b..0cef818 100644 --- a/packages/core/src/assets/icons.ts +++ b/packages/core/src/assets/icons.ts @@ -147,4 +147,12 @@ export const icons = { `, + + emoji: ` + Emoji + + + + + `, }; diff --git a/packages/core/src/config/editorConfig.ts b/packages/core/src/config/editorConfig.ts index 6595eee..0567289 100644 --- a/packages/core/src/config/editorConfig.ts +++ b/packages/core/src/config/editorConfig.ts @@ -9,7 +9,7 @@ const featureGroups = { formatting: ['bold', 'italic', 'underline', 'strikethrough'], alignment: ['alignLeft', 'alignCenter', 'alignRight'], lists: ['unorderedList', 'orderedList'], - media: ['hyperlink', 'image'], + media: ['hyperlink', 'image', 'emoji'], utility: ['getHtmlContent', 'loadHtmlContent'], }; @@ -100,6 +100,7 @@ export function createEditor( fontColor: 'Text Color', bgColor: 'Highlight Color', image: 'Insert Image', + emoji: 'Emoji', getHtmlContent: 'Get HTML', loadHtmlContent: 'Load HTML', }; @@ -111,6 +112,7 @@ export function createEditor( { feature: 'unorderedList', id: 'unorderedList', icon: icons.bullet_list }, { feature: 'orderedList', id: 'orderedList', icon: icons.numbered_list }, { feature: 'hyperlink', id: 'hyperlink', icon: icons.hyperlink }, + { feature: 'emoji', id: 'emoji', icon: icons.emoji }, { feature: 'strikethrough', id: 'strikethrough', diff --git a/packages/core/src/constants/emojis.ts b/packages/core/src/constants/emojis.ts new file mode 100644 index 0000000..8a01e10 --- /dev/null +++ b/packages/core/src/constants/emojis.ts @@ -0,0 +1,23 @@ +import { EmojiCategory } from '../types/emoji.type'; + +export const EMOJI_CATEGORIES: EmojiCategory[] = [ + { + label: 'Smileys & People', + items: [ + { char: '😀', name: 'grinning face', shortcode: ':grinning:' }, + { char: '😃', name: 'big eyes smile', shortcode: ':smiley:' }, + { char: '😄', name: 'smiling eyes grin', shortcode: ':smile:' }, + { char: '😁', name: 'beaming grin', shortcode: ':grin:' }, + { char: '😆', name: 'squinting laugh', shortcode: ':laughing:' }, + { char: '😅', name: 'sweat smile', shortcode: ':sweat_smile:' }, + { char: '🤣', name: 'rolling floor laughing', shortcode: ':rofl:' }, + { char: '😂', name: 'tears of joy', shortcode: ':joy:' }, + { + char: '🙂', + name: 'slightly smiling', + shortcode: ':slightly_smiling_face:', + }, + { char: '😊', name: 'smiling eyes blush', shortcode: ':blush:' }, + ], + }, +]; diff --git a/packages/core/src/types/emoji.type.ts b/packages/core/src/types/emoji.type.ts new file mode 100644 index 0000000..2c2eede --- /dev/null +++ b/packages/core/src/types/emoji.type.ts @@ -0,0 +1,10 @@ +export interface EmojiItem { + char: string; + name: string; + shortcode: string; +} + +export interface EmojiCategory { + label: string; + items: EmojiItem[]; +} diff --git a/packages/core/src/view/emojiPickerView.ts b/packages/core/src/view/emojiPickerView.ts new file mode 100644 index 0000000..3b5a7c6 --- /dev/null +++ b/packages/core/src/view/emojiPickerView.ts @@ -0,0 +1,243 @@ +import { EMOJI_CATEGORIES } from '../constants/emojis'; +import { EmojiItem } from '../types/emoji.type'; + +const RECENT_KEY = 'recent_emojies'; +const MAX_RECENT = 24; + +class EmojiPickerView { + private popup: HTMLElement; + private gridArea: HTMLElement; + private searchInput: HTMLInputElement; + private onSelectCallback?: (char: string) => void; + private isOpen: boolean = false; + + constructor() { + this.popup = this.buildPopup(); + this.gridArea = this.popup.querySelector('.emoji_grid') as HTMLElement; + this.searchInput = this.popup.querySelector( + '.emoji_serch' + ) as HTMLInputElement; + document.body.appendChild(this.popup); + + // in outside click close the modal + document.addEventListener('mousedown', e => { + if (this.isOpen && !this.popup.contains(e.target as Node)) { + const clickedBtn = (e.target as HTMLElement).closest( + '[data-action="emoji"]' + ); + if (!clickedBtn) this.close(); + } + }); + } + + onSelect(cb: (char: string) => void) { + this.onSelectCallback = cb; + } + + open(element: HTMLElement) { + const rect = element.getBoundingClientRect(); + const popupWidth = 320; + let left = rect.left + window.scrollX; + if (left + popupWidth > window.innerWidth - 8) { + left = window.innerWidth - popupWidth - 8; + } + const top = rect.bottom + window.scrollY + 4; + + this.popup.style.left = `${left}px`; + this.popup.style.top = `${top}px`; + this.popup.style.display = 'flex'; + this.isOpen = true; + + // reset the state + this.searchInput.value = ''; + this.renderGrid(''); + } + + close() { + this.popup.style.display = 'none'; + this.isOpen = false; + } + + getIsOpen() { + return this.isOpen; + } + + private buildPopup(): HTMLElement { + const popup = document.createElement('div'); + popup.style.cssText = ` + position: absolute; + display: none; + flex-direction: column; + width: 320px; + max-height: 380px; + background: #ffffff; + border: 1px solid #dddddd; + border-radius: 10px; + box-shadow: 0 6px 24px rgba(0,0,0,0.14); + z-index: 9999; + overflow: hidden; + font-family: system-ui, -apple-system, sans-serif; + `; + + const header = document.createElement('div'); + header.style.cssText = ` + display: flex; + align-items: center; + gap: 8px; + padding: 10px 12px; + border-bottom: 1px solid #f0f0f0; + background: #fafafa; + `; + + const search = document.createElement('input'); + search.type = 'text'; + search.placeholder = '🔍 Search emojis or :shortcode:'; + search.className = 'emoji_serch'; + search.style.cssText = ` + flex: 1; + padding: 6px 10px; + border: 1px solid #ccc; + border-radius: 6px; + font-size: 13px; + outline: none; + background: #fff; + `; + search.addEventListener('input', () => + this.renderGrid(search.value.trim()) + ); + + header.appendChild(search); + + const gridArea = document.createElement('div'); + gridArea.className = 'emoji_grid'; + gridArea.style.cssText = ` + flex: 1; + overflow-y: auto; + padding: 10px 12px 12px; + `; + + popup.appendChild(header); + popup.appendChild(gridArea); + + return popup; + } + + private getRecentEmojis(): EmojiItem[] { + try { + const raw = localStorage.getItem(RECENT_KEY); + return raw ? JSON.parse(raw) : []; + } catch { + return []; + } + } + + private saveRecentEmoji(item: EmojiItem) { + const recents = this.getRecentEmojis().filter(e => e.char !== item.char); + recents.unshift(item); + if (recents.length > MAX_RECENT) recents.length = MAX_RECENT; + try { + localStorage.setItem(RECENT_KEY, JSON.stringify(recents)); + } catch (e) { + console.error('Problem occur in saving emojies', e); + } + } + + private resolveChar(item: EmojiItem): string { + return item.char; + } + + private renderGrid(query: string) { + this.gridArea.innerHTML = ''; + const q = query.toLowerCase().replace(/^:/, '').replace(/:$/, ''); + + const renderCategory = (label: string, items: EmojiItem[]) => { + if (!items.length) return; + + const section = document.createElement('div'); + section.style.marginBottom = '12px'; + + const title = document.createElement('div'); + title.textContent = label; + title.style.cssText = ` + font-size: 11px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.5px; + color: #999; + margin-bottom: 6px; + `; + section.appendChild(title); + + const grid = document.createElement('div'); + grid.style.cssText = ` + display: grid; + grid-template-columns: repeat(8, 1fr); + gap: 2px; + `; + + items.forEach(item => { + const char = this.resolveChar(item); + const btn = document.createElement('button'); + btn.textContent = char; + btn.title = `${item.name} ${item.shortcode}`; + btn.style.cssText = ` + font-size: 20px; + background: transparent; + border: none; + cursor: pointer; + border-radius: 5px; + padding: 4px; + line-height: 1.2; + transition: background 0.1s; + aspect-ratio: 1; + display: flex; + align-items: center; + justify-content: center; + `; + btn.addEventListener( + 'mouseenter', + () => (btn.style.background = '#f0f0f0') + ); + btn.addEventListener( + 'mouseleave', + () => (btn.style.background = 'transparent') + ); + btn.addEventListener('mousedown', e => { + e.preventDefault(); + this.saveRecentEmoji(item); + this.onSelectCallback?.(char); + }); + grid.appendChild(btn); + }); + + section.appendChild(grid); + this.gridArea.appendChild(section); + }; + + if (!q) { + const recents = this.getRecentEmojis(); + renderCategory('Recently Used', recents); + EMOJI_CATEGORIES.forEach(cat => renderCategory(cat.label, cat.items)); + } else { + const results: EmojiItem[] = []; + EMOJI_CATEGORIES.forEach(cat => { + cat.items.forEach(item => { + if (item.name.includes(q) || item.shortcode.includes(q)) { + results.push(item); + } + }); + }); + renderCategory(`Results for "${q}"`, results); + } + + if (!this.gridArea.querySelector('button')) { + const empty = document.createElement('div'); + empty.textContent = 'No emojis found'; + empty.style.cssText = + 'text-align: center; color: #aaa; padding: 24px 0; font-size: 13px;'; + this.gridArea.appendChild(empty); + } + } +} + +export default EmojiPickerView;