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) • 7.92 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 C=Object.defineProperty;var y=(d,e,t)=>e in d?C(d,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):d[e]=t;var p=(d,e,t)=>y(d,typeof e!="symbol"?e+"":e,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});;/* empty css */;/* empty css */const S=require("../ToolbarPlugin/utils.cjs"),T=require("../../core/ui/PopupManager.cjs"),a=require("../../utils/helpers.cjs"),A=require("../../icons/style.svg.cjs"),h=require("./constants.cjs");class B{constructor(){p(this,"name","block-style");p(this,"editor",null);p(this,"toolbarButton",null);p(this,"popup",null);p(this,"selectedElement",null)}initialize(e){this.editor=e,this.popup=new T.PopupManager(e,{title:e.t("Block Style Editor"),className:"block-style-editor",closeOnClickOutside:!0,items:this.createPopupItems(),buttons:[{label:e.t("Apply"),variant:"primary",onClick:()=>this.applyStyles()},{label:e.t("Cancel"),variant:"secondary",onClick:()=>{var t;return(t=this.popup)==null?void 0:t.hide()}}]}),this.addToolbarButton(),this.editor.on("selectionchange",()=>this.handleSelectionChange())}addToolbarButton(){var t,n;const e=(t=this.editor)==null?void 0:t.getToolbar();e&&(this.toolbarButton=S.createToolbarButton({icon:A.default,title:(n=this.editor)==null?void 0:n.t("Block Style"),onClick:()=>this.showPopup()}),e.appendChild(this.toolbarButton))}handleSelectionChange(){var s,l,o,r,i,u;const e=(l=(s=this.editor)==null?void 0:s.getTextFormatter())==null?void 0:l.getSelection();if(!e||e.rangeCount===0)return;const t=e.getRangeAt(0);let n=null;if(this.editor){if(t.commonAncestorContainer.nodeType===Node.TEXT_NODE?n=t.commonAncestorContainer.parentElement:t.commonAncestorContainer.nodeType===Node.ELEMENT_NODE&&(n=t.commonAncestorContainer),n===((o=this.editor)==null?void 0:o.getContainer())){this.selectedElement=null,(r=this.toolbarButton)==null||r.classList.remove("active");return}if(n){const c=this.findNearestBlockElement(n);if(c&&this.isBlockElement(c)){this.selectedElement=c,(i=this.toolbarButton)==null||i.classList.add("active"),console.log("BlockStylePlugin: Selected element:",c.tagName,c);return}}this.selectedElement=null,(u=this.toolbarButton)==null||u.classList.remove("active"),console.log("BlockStylePlugin: No block element found")}}findNearestBlockElement(e){var n;let t=e;for(;t&&t!==((n=this.editor)==null?void 0:n.getContainer());){if(this.isBlockElement(t))return t;t=t.parentElement}return null}getCurrentBlockElement(){var s,l,o;const e=(l=(s=this.editor)==null?void 0:s.getTextFormatter())==null?void 0:l.getSelection();if(!e||e.rangeCount===0)return null;const t=e.getRangeAt(0);let n=null;return t.commonAncestorContainer.nodeType===Node.TEXT_NODE?n=t.commonAncestorContainer.parentElement:t.commonAncestorContainer.nodeType===Node.ELEMENT_NODE&&(n=t.commonAncestorContainer),!n||n===((o=this.editor)==null?void 0:o.getContainer())?null:this.findNearestBlockElement(n)}isBlockElement(e){return["DIV","P","H1","H2","H3","H4","H5","H6","SECTION","ARTICLE","HEADER","FOOTER","NAV","ASIDE","MAIN","FIGURE","FIGCAPTION","BLOCKQUOTE","UL","OL","LI","DL","DT","DD","PRE","HR","ADDRESS","TABLE","THEAD","TBODY","TFOOT","TR","TH","TD","CAPTION","FORM","FIELDSET","LEGEND","DETAILS","SUMMARY","MENU","DIALOG","IFRAME","CANVAS","VIDEO","AUDIO","PICTURE","SOURCE","TRACK","MAP","OBJECT","PARAM","EMBED","NOSCRIPT","PROGRESS","METER","TIME","MARK","RUBY","RT","RP","BDI","BDO","WBR","INS","DEL","CODE","KBD","SAMP","VAR","CITE","Q","ABBR","DFN","SMALL","STRONG","EM","I","B","U","S","STRIKE","SUB","SUP","SPAN","BR","IMG","A","BUTTON","INPUT","TEXTAREA","SELECT","OPTION","OPTGROUP","LABEL","OUTPUT","DATALIST","KEYGEN","ISINDEX","BASE","LINK","META","STYLE","SCRIPT","TITLE","HEAD","BODY","HTML"].includes(e.tagName)}createPopupItems(){return[{type:"custom",id:"style-editor",content:()=>this.createStyleEditor()},{type:"custom",id:"class-editor",content:()=>this.createClassEditor()}]}createStyleEditor(){var o,r,i;const e=a.createContainer("popup-item"),t=document.createElement("label");t.textContent=((o=this.editor)==null?void 0:o.t("Inline Styles"))||"Inline Styles",e.appendChild(t);const n=a.createContainer("style-list");(((i=(r=this.selectedElement)==null?void 0:r.getAttribute("style"))==null?void 0:i.split(";"))||[]).forEach(u=>{if(u.trim()){const[c,m]=u.split(":").map(E=>E.trim());if(c&&m){const E=this.createStyleItem(c,m);n.appendChild(E)}}});const l=a.createButton("Add Style",()=>this.addStyle(n));return l.className="add-button",e.appendChild(n),e.appendChild(l),e}createStyleItem(e,t){const n=a.createContainer("style-item"),s=document.createElement("select");s.className="style-property-select",Object.keys(h.AVAILABLE_STYLES).forEach(r=>{const i=document.createElement("option");i.value=r,i.textContent=r,i.selected=r===e,s.appendChild(i)});const l=document.createElement("select");l.className="style-value-select",s.addEventListener("change",()=>{this.updateValueSelect(l,s.value)}),this.updateValueSelect(l,s.value,t);const o=a.createButton("×",()=>n.remove());return o.className="remove-button",n.appendChild(s),n.appendChild(l),n.appendChild(o),n}updateValueSelect(e,t,n=""){e.innerHTML="",(h.AVAILABLE_STYLES[t]||[]).forEach(l=>{const o=document.createElement("option");o.value=l,o.textContent=l,o.selected=l===n,e.appendChild(o)})}addStyle(e){const t=this.createStyleItem("","");e.appendChild(t)}createClassEditor(){var o,r,i;const e=a.createContainer("popup-item"),t=document.createElement("label");t.textContent=((o=this.editor)==null?void 0:o.t("CSS Classes"))||"CSS Classes",e.appendChild(t);const n=a.createContainer("class-list");(((i=(r=this.selectedElement)==null?void 0:r.getAttribute("class"))==null?void 0:i.split(" "))||[]).forEach(u=>{if(u.trim()){const c=this.createClassItem(u);n.appendChild(c)}});const l=a.createButton("Add Class",()=>this.addClass(n));return l.className="add-button",e.appendChild(n),e.appendChild(l),e}createClassItem(e){const t=a.createContainer("class-item"),n=a.createInputField("text","Enter class (e.g., my-class)",e);n.className="class-input";const s=a.createButton("×",()=>t.remove());return s.className="remove-button",t.appendChild(n),t.appendChild(s),t}addClass(e){const t=this.createClassItem("");e.appendChild(t)}showPopup(){if(!this.popup)return;const e=this.getCurrentBlockElement();if(console.log("BlockStylePlugin: showPopup called, currentBlockElement:",e),!e){const l=document.createElement("div");l.innerHTML="<p>Please select a block element to style.</p>",this.popup.setContent(l),this.popup.show();return}this.selectedElement=e;const t=document.createElement("div"),n=this.createStyleEditor(),s=this.createClassEditor();t.appendChild(n),t.appendChild(s),this.popup.setContent(t),this.popup.show()}applyStyles(){var n,s,l;if(!this.selectedElement||!this.popup)return;(n=this.editor)==null||n.ensureEditorFocus();const e=(s=this.popup.getElement())==null?void 0:s.querySelector(".style-list"),t=(l=this.popup.getElement())==null?void 0:l.querySelector(".class-list");if(e){const o=Array.from(e.querySelectorAll(".style-item")).map(r=>{const i=r.querySelector(".style-property-select"),u=r.querySelector(".style-value-select"),c=i.value.trim(),m=u.value.trim();return c&&m?`${c}: ${m}`:""}).filter(r=>r).join("; ");this.selectedElement.setAttribute("style",o)}if(t){const o=Array.from(t.querySelectorAll(".class-input")).map(r=>r.value.trim()).filter(r=>r).join(" ");this.selectedElement.setAttribute("class",o)}this.popup.hide()}destroy(){var e,t,n;(e=this.toolbarButton)==null||e.remove(),this.toolbarButton=null,(t=this.editor)==null||t.off("selectionchange"),(n=this.popup)==null||n.destroy(),this.popup=null,this.editor=null}}exports.BlockStylePlugin=B;