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

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