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
4 lines (3 loc) • 6.2 kB
JavaScript
/*! 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 E=Object.defineProperty;var C=(u,e,t)=>e in u?E(u,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):u[e]=t;var c=(u,e,t)=>C(u,typeof e!="symbol"?e+"":e,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});;/* empty css */;/* empty css */const L=require("../ToolbarPlugin/utils.cjs"),N=require("../../icons/list-bullet.svg.cjs"),B=require("../../icons/list-numbered.svg.cjs"),y=require("../../utils/helpers.cjs");class T{constructor(){c(this,"name","lists");c(this,"hotkeys",[{keys:"Ctrl+Shift+B",description:"Bulleted list",command:"lists-unordered",icon:"•"},{keys:"Ctrl+Shift+N",description:"Numbered list",command:"lists-ordered",icon:"1️⃣"}]);c(this,"editor",null);c(this,"ulButton",null);c(this,"olButton",null);c(this,"handleKeydown",e=>{(e.metaKey||e.ctrlKey)&&e.key==="Enter"&&(e.preventDefault(),this.exitListAndInsertBreak())})}initialize(e){this.editor=e,this.addToolbarButtons(),this.setupListHandling(),this.editor.on("lists-unordered",()=>{var t;(t=this.editor)==null||t.ensureEditorFocus(),this.toggleList("unordered")}),this.editor.on("lists-ordered",()=>{var t;(t=this.editor)==null||t.ensureEditorFocus(),this.toggleList("ordered")})}addToolbarButtons(){var t,o,i,n;const e=(t=this.editor)==null?void 0:t.getToolbar();e&&(this.ulButton=L.createToolbarButton({icon:N.default,title:(o=this.editor)==null?void 0:o.t("Bullet List"),onClick:()=>{var s;(s=this.editor)==null||s.ensureEditorFocus(),this.toggleList("unordered"),this.handleSelectionChange()}}),this.olButton=L.createToolbarButton({icon:B.default,title:(i=this.editor)==null?void 0:i.t("Numbered List"),onClick:()=>{var s;(s=this.editor)==null||s.ensureEditorFocus(),this.toggleList("ordered"),this.handleSelectionChange()}}),e.appendChild(this.ulButton),e.appendChild(this.olButton),(n=this.editor)==null||n.on("selectionchange",()=>this.handleSelectionChange()))}handleSelectionChange(){var n,s,r,d,a,l,m,g,h;const e=(s=(n=this.editor)==null?void 0:n.getTextFormatter())==null?void 0:s.getSelection();if(!e||!e.rangeCount)return;const o=e.getRangeAt(0).commonAncestorContainer,i=o.nodeType===Node.ELEMENT_NODE?o.closest("ul, ol"):(r=o.parentElement)==null?void 0:r.closest("ul, ol");i?i.tagName==="UL"?((d=this.ulButton)==null||d.classList.add("active"),(a=this.olButton)==null||a.classList.remove("active")):i.tagName==="OL"&&((l=this.olButton)==null||l.classList.add("active"),(m=this.ulButton)==null||m.classList.remove("active")):((g=this.ulButton)==null||g.classList.remove("active"),(h=this.olButton)==null||h.classList.remove("active"))}setupListHandling(){this.editor&&this.editor.getContainer().addEventListener("keydown",this.handleKeydown)}exitListAndInsertBreak(){var i,n,s,r,d;const e=(n=(i=this.editor)==null?void 0:i.getTextFormatter())==null?void 0:n.getSelection();if(!e||!e.rangeCount)return;const t=e.getRangeAt(0),o=(s=t.commonAncestorContainer.parentElement)==null?void 0:s.closest("li");if(o){const a=o.parentElement;if(!a)return;const l=y.createP("my-4");a.nextSibling?(r=a.parentNode)==null||r.insertBefore(l,a.nextSibling):(d=a.parentNode)==null||d.appendChild(l),t.selectNodeContents(l),t.collapse(!0),e.removeAllRanges(),e.addRange(t)}}toggleList(e){var s,r;if(!this.editor)return;const t=(s=this.editor.getTextFormatter())==null?void 0:s.getSelection();if(!t||!t.rangeCount)return;const o=t.getRangeAt(0),i=o.commonAncestorContainer,n=i.nodeType===Node.ELEMENT_NODE?i.closest("ul, ol"):(r=i.parentElement)==null?void 0:r.closest("ul, ol");n?e==="ordered"&&n.tagName==="OL"||e==="unordered"&&n.tagName==="UL"?this.unwrapList(n):this.replaceList(n,e):this.createNewList(o,e)}unwrapList(e){var s,r,d;const t=Array.from(e.querySelectorAll("li")),o=document.createElement("div");t.forEach((a,l)=>{o.appendChild(document.createTextNode(a.textContent||"")),l<t.length-1&&o.appendChild(document.createElement("br"))}),(s=e.parentNode)==null||s.replaceChild(o,e);const i=document.createRange();i.selectNodeContents(o);const n=(d=(r=this.editor)==null?void 0:r.getTextFormatter())==null?void 0:d.getSelection();n==null||n.removeAllRanges(),n==null||n.addRange(i)}replaceList(e,t){var n;const o=t==="ordered"?"ol":"ul",i=document.createElement(o);Array.from(e.children).forEach(s=>{const r=document.createElement("li");r.innerHTML=s.innerHTML,i.appendChild(r)}),(n=e.parentNode)==null||n.replaceChild(i,e),this.applyListStyles(i,t)}createNewList(e,t){var d,a;const o=e.extractContents(),i=t==="ordered"?"ol":"ul",n=document.createElement(i);if(Array.from(o.childNodes).forEach(l=>{var m,g;if(l.nodeType===Node.TEXT_NODE)(((m=l.textContent)==null?void 0:m.split(`
`).filter(p=>p.trim()!==""))||[]).forEach(p=>{const f=document.createElement("li");f.textContent=p.trim(),n.appendChild(f)});else if(l.nodeName!=="BR"){if(l.nodeType===Node.ELEMENT_NODE&&((g=l.textContent)==null?void 0:g.trim())!==""){const h=document.createElement("li");h.appendChild(l.cloneNode(!0)),n.appendChild(h)}}}),n.children.length===0){const l=document.createElement("li");l.textContent="List item",n.appendChild(l)}e.insertNode(n),this.applyListStyles(n,t);const s=document.createRange();s.selectNodeContents(n.lastElementChild||n);const r=(a=(d=this.editor)==null?void 0:d.getTextFormatter())==null?void 0:a.getSelection();r==null||r.removeAllRanges(),r==null||r.addRange(s)}applyListStyles(e,t){t==="ordered"?e.className="list-decimal pl-8 my-4 space-y-2":e.className="list-disc pl-8 my-4 space-y-2",e.querySelectorAll("li").forEach(o=>{o.className="pl-2"})}destroy(){var e,t;this.editor&&this.editor.getContainer().removeEventListener("keydown",this.handleKeydown),this.ulButton&&this.ulButton.parentElement&&this.ulButton.parentElement.removeChild(this.ulButton),this.olButton&&this.olButton.parentElement&&this.olButton.parentElement.removeChild(this.olButton),(e=this.editor)==null||e.off("selectionchange"),(t=this.editor)==null||t.off("lists"),this.editor=null,this.ulButton=null,this.olButton=null}}exports.ListsPlugin=T;