UNPKG

on-codemerge

Version:

A WYSIWYG editor for on-codemerge is a user-friendly interface that allows users to edit and view their code in real time, exactly as it will appear in the final product

3 lines (2 loc) 5.36 kB
/*! on-codemerge v1.3.1 @author Pavel Kuzmin @license MIT @homepage https://s00d.github.io/on-codemerge/ @repository git+https://github.com/s00d/on-codemerge.git Copyright (c) 2026 Pavel Kuzmin - Built on 2026-07-02T13:39:17.947Z */ "use strict";var p=Object.defineProperty;var C=(d,t,e)=>t in d?p(d,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):d[t]=e;var l=(d,t,e)=>C(d,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});;/* empty css */;/* empty css */const f=require("./services/CommentManager.cjs"),g=require("./components/CommentMenu.cjs"),M=require("./components/ErrorModal.cjs"),b=require("../ToolbarPlugin/utils.cjs"),k=require("../../icons/comment.svg.cjs"),v=require("../../icons/comment-marker.svg.cjs"),c=require("../../utils/helpers.cjs");class y{constructor(){l(this,"name","comments");l(this,"hotkeys",[{keys:"Ctrl+Alt+J",description:"Insert comment",command:"comment",icon:"💬"}]);l(this,"editor",null);l(this,"manager");l(this,"menu",null);l(this,"errorModal",null);l(this,"tooltip");l(this,"toolbarButton",null);this.manager=new f.CommentManager,this.tooltip=this.createTooltip()}initialize(t){this.errorModal=new M.ErrorModal(t),this.menu=new g.CommentMenu(t),this.editor=t,this.editor.getDOMContext().appendChild(this.tooltip),this.addToolbarButton(),this.setupEventListeners(),this.editor.on("comment",()=>{this.addComment()})}createTooltip(){const t=c.createContainer("comment-tooltip");return t.style.display="none",t}addToolbarButton(){var e,o;const t=(e=this.editor)==null?void 0:e.getToolbar();t&&(this.toolbarButton=b.createToolbarButton({icon:k.default,title:(o=this.editor)==null?void 0:o.t("Insert Comment"),onClick:()=>this.addComment()}),t.appendChild(this.toolbarButton))}setupEventListeners(){this.editor&&(this.handleMouseOver=this.handleMouseOver.bind(this),this.handleMouseOut=this.handleMouseOut.bind(this),this.handleClick=this.handleClick.bind(this))}handleMouseOver(t){const e=t.target.closest(".comment-marker");if(e instanceof HTMLElement){const o=e.getAttribute("data-comment-id");o&&this.showTooltip(e,o)}}handleMouseOut(t){t.target.closest(".comment-marker")&&this.hideTooltip()}handleClick(t){const e=t.target.closest(".comment-marker");if(e instanceof HTMLElement){const o=e.getAttribute("data-comment-id");o&&this.editComment(o)}}showTooltip(t,e){const o=this.manager.getComment(e);if(!o)return;this.tooltip.textContent=o.content,this.tooltip.style.display="block";const i=t.getBoundingClientRect();this.tooltip.style.left=`${i.left+i.width/2}px`,this.tooltip.style.top=`${i.bottom+8}px`}hideTooltip(){this.tooltip.style.display="none"}addComment(){var o,i,a,r,s,n;if(!this.editor){(o=this.errorModal)==null||o.show("Editor not initialized");return}const t=(i=this.editor.getTextFormatter())==null?void 0:i.getSelection();if(!t||!t.rangeCount){(a=this.errorModal)==null||a.show(this.editor.t("Please select some text to comment on"));return}const e=t.getRangeAt(0);if(!this.isRangeInsideEditor(e)){(r=this.errorModal)==null||r.show(this.editor.t("Please select text inside the editor"));return}if(e.collapsed){(s=this.errorModal)==null||s.show(this.editor.t("Please select some text to comment on"));return}(n=this.menu)==null||n.show((m,h)=>{if(h==="save"){const u=this.manager.createComment(m);this.insertCommentMarker(u.id,e)}})}isRangeInsideEditor(t){var o;const e=(o=this.editor)==null?void 0:o.getContainer();return e?e.contains(t.startContainer)&&e.contains(t.endContainer):!1}editComment(t){var o;const e=this.manager.getComment(t);e&&((o=this.menu)==null||o.show((i,a)=>{var r;if(a==="save")this.manager.updateComment(t,i);else if(a==="delete"){this.manager.deleteComment(t);const s=(r=this.editor)==null?void 0:r.getContainer().querySelector(`[data-comment-id="${t}"]`);if(s){const n=s.previousElementSibling;if(n!=null&&n.classList.contains("commented-text")){const m=n.parentNode;if(m){for(;n.firstChild;)m.insertBefore(n.firstChild,n);n.remove(),s.remove()}}}}},e.content,!0))}insertCommentMarker(t,e){var o,i,a;try{const r=e.cloneContents(),s=c.createSpan("commented-text");s.appendChild(r);const n=c.createSpan("comment-marker");n.setAttribute("data-comment-id",t),n.innerHTML=v.default;const m=document.createDocumentFragment();m.appendChild(s),m.appendChild(n),e.deleteContents(),e.insertNode(m),e.setStartAfter(n),e.setEndAfter(n);const h=(o=this.editor.getTextFormatter())==null?void 0:o.getSelection();h&&(h.removeAllRanges(),h.addRange(e))}catch(r){console.error("Failed to insert comment:",r),(a=this.errorModal)==null||a.show(((i=this.editor)==null?void 0:i.t("Failed to insert comment. Please try selecting a simpler text range."))??"")}}destroy(){var t;if(this.editor){const e=this.editor.getContainer();e.removeEventListener("mouseover",this.handleMouseOver),e.removeEventListener("mouseout",this.handleMouseOut),e.removeEventListener("click",this.handleClick)}this.tooltip&&this.tooltip.parentElement&&this.tooltip.parentElement.removeChild(this.tooltip),this.toolbarButton&&(this.toolbarButton.remove(),this.toolbarButton=null),this.menu&&(this.menu.destroy(),this.menu=null),this.errorModal&&(this.errorModal.destroy(),this.errorModal=null),(t=this.editor)==null||t.off("comment"),this.editor=null,this.menu=null,this.errorModal=null,this.tooltip=null,this.manager=null}}exports.CommentsPlugin=y;