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) • 4.28 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 u=Object.defineProperty;var f=(d,t,e)=>t in d?u(d,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):d[t]=e;var c=(d,t,e)=>f(d,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const m=require("../../../core/ui/PopupManager.cjs"),C=require("../utils/formatters.cjs"),y=require("../utils/diff.cjs"),v=require("../../../icons/close.svg.cjs"),s=require("../../../utils/helpers.cjs");class g{constructor(t){c(this,"editor");c(this,"popup");c(this,"states",[]);c(this,"currentIndex",-1);c(this,"selectedIndex",-1);c(this,"onRestore",null);this.editor=t,this.popup=new m.PopupManager(t,{className:"history-viewer-modal",closeOnClickOutside:!0,items:[{type:"custom",id:"html-viewer-content",content:()=>this.createContent()}]})}createContent(){const t=s.createContainer("p-4"),e=s.createContainer("flex items-center justify-between mb-4"),n=s.createH("h3","text-lg font-semibold",this.editor.t("Edit History")),i=s.createButton("",()=>{this.popup.hide()});i.className="close-button",i.innerHTML=v.default,e.appendChild(n),e.appendChild(i);const o=s.createContainer("grid grid-cols-2 gap-4"),r=s.createContainer("history-list max-h-[60vh] overflow-y-auto"),p=s.createContainer("diff-view max-h-[60vh] overflow-y-auto p-3 bg-gray-50 rounded-lg");return o.appendChild(r),o.appendChild(p),t.appendChild(e),t.appendChild(o),t.addEventListener("click",a=>{const l=a.target.closest("[data-index]");if(!l)return;const h=parseInt(l.getAttribute("data-index")||"0",10);this.selectedIndex=h,this.showDiff(h)}),t}renderHistoryList(){const t=this.popup.getElement().querySelector(".history-list");t&&(t.innerHTML="",this.states.forEach((e,n)=>{const i=this.createHistoryItem(e,n);t.appendChild(i)}))}createHistoryItem(t,e){const n=s.createContainer(`history-item ${e===this.currentIndex?"current":""} ${e===this.selectedIndex?"selected":""}`);n.dataset.index=e.toString();const i=s.createContainer("flex items-center justify-between p-3 hover:bg-gray-50 rounded-lg cursor-pointer"),o=s.createContainer(),r=s.createContainer("text-sm font-medium");r.textContent=`Version ${e+1}`;const p=s.createContainer("ext-xs text-gray-500",C.formatTimestamp(t.timestamp));o.appendChild(r),o.appendChild(p);const a=s.createButton(this.editor.t("Restore"),l=>{l.preventDefault();const h=this.states[e];h&&this.onRestore&&(this.onRestore(h.content),this.popup.hide())});return a.className="restore-button px-2 py-1 text-sm text-blue-600 hover:bg-blue-50 rounded",a.textContent=this.editor.t("Restore"),i.appendChild(o),i.appendChild(a),n.appendChild(i),n}showDiff(t){const e=this.popup.getElement().querySelector(".diff-view");if(!e)return;const n=this.states[t],i=t>0?this.states[t-1]:{content:""},o=y.computeDiff(i.content,n.content),r=this.renderDiff(o);e.innerHTML="";const p=s.createContainer("text-sm mb-2 text-gray-500");p.textContent=t>0?this.editor.t("Changes from previous version:"):this.editor.t("Initial version");const a=s.createContainer("diff-content");a.innerHTML=r,e.appendChild(p),e.appendChild(a)}renderDiff(t){return t.map(e=>{switch(e.type){case"add":return`<span class="diff-add">${e.value}</span>`;case"remove":return`<span class="diff-remove">${e.value}</span>`;default:return e.value}}).join("")}show(t,e,n){this.states=t,this.currentIndex=e,this.selectedIndex=e,this.onRestore=n,this.renderHistoryList(),this.showDiff(e),this.popup.show()}destroy(){this.popup.destroy&&this.popup.destroy();const t=this.popup.getElement();if(t){const e=t.querySelector(".close-button");e==null||e.removeEventListener("click",()=>{this.popup.hide()}),t.removeEventListener("click",n=>{const i=n.target.closest("[data-index]");if(!i)return;const o=parseInt(i.getAttribute("data-index")||"0",10);if(n.target.closest(".restore-button")){const r=this.states[o];r&&this.onRestore&&(this.onRestore(r.content),this.popup.hide())}else this.selectedIndex=o,this.showDiff(o)})}this.states=[],this.currentIndex=-1,this.selectedIndex=-1,this.onRestore=null,this.editor=null,this.popup=null}}exports.HistoryViewerModal=g;