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

177 lines (176 loc) 7.04 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 o = Object.defineProperty; var h = (s, e, t) => e in s ? o(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t; var i = (s, e, t) => h(s, typeof e != "symbol" ? e + "" : e, t); import { PopupManager as p } from "../../../core/ui/PopupManager.mjs"; import { MathRenderer as l } from "../services/MathRenderer.mjs"; import { createContainer as a, createLabel as d, createTextarea as c } from "../../../utils/helpers.mjs"; import { MathToolbar as u } from "./MathToolbar.mjs"; class b { constructor(e) { i(this, "editor"); i(this, "mathToolbar"); i(this, "popup"); i(this, "renderer"); i(this, "onInsert", null); i(this, "editingMath", null); i(this, "expressionInput", null); i(this, "previewContainer", null); i(this, "expression", ""); i(this, "handleInsertSymbol", (e) => { if (!this.expressionInput) return; const t = this.expressionInput.selectionStart, n = this.expressionInput.value; this.expressionInput.value = n.slice(0, t) + e + n.slice(t), this.expressionInput.focus(), this.expressionInput.setSelectionRange(t + e.length, t + e.length), this.handleInputChange(this.expressionInput.value); }); this.editor = e, this.renderer = new l(), this.mathToolbar = new u(this.handleInsertSymbol), this.popup = new p(e, { title: e.t("Insert Math"), className: "math-menu", closeOnClickOutside: !0, buttons: [ { label: e.t("Cancel"), variant: "secondary", onClick: () => this.popup.hide() }, { label: e.t("Insert"), variant: "primary", onClick: () => this.handleSubmit() } ], items: this.createPopupItems() }); } createPopupItems() { return [ { type: "custom", id: "math-editor-container", content: () => this.createMathEditorContainer() }, { type: "custom", id: "formula-help-section", content: () => this.createFormulaHelpSection() }, { type: "custom", id: "preview-math-container", content: () => this.createPreviewContainer() } ]; } createFormulaHelpSection() { const e = a("formula-help-section mt-4"), t = document.createElement("div"); t.className = "flex items-center justify-between cursor-pointer", t.innerHTML = ` <span class="text-lg font-semibold m-0 text-gray-800">How to Write Formulas</span> <span class="arrow">▼</span> `; const n = a("formula-help-content hidden mt-2"); return n.innerHTML = ` <p class="text-gray-600"> Use LaTeX syntax to write mathematical expressions. Below are some examples: </p> <div class="mt-4 space-y-2"> <div> <strong>Example 1:</strong> Quadratic formula <pre class="bg-gray-100 p-2 rounded-md">x = \\frac{-b \\pm \\sqrt{b^2 - 4ac}}{2a}</pre> </div> <div> <strong>Example 2:</strong> Integral <pre class="bg-gray-100 p-2 rounded-md">\\int_{a}^{b} x^2 \\, dx</pre> </div> <div> <strong>Example 3:</strong> Matrix <pre class="bg-gray-100 p-2 rounded-md"> \\begin{bmatrix} 1 & 2 \\\\ 3 & 4 \\end{bmatrix} </pre> </div> <div> <strong>Example 4:</strong> Greek letters <pre class="bg-gray-100 p-2 rounded-md">\\alpha, \\beta, \\gamma</pre> </div> </div> <p class="mt-4 text-gray-600"> For more information, refer to the <a href="https://en.wikibooks.org/wiki/LaTeX/Mathematics" target="_blank" class="text-blue-500 hover:underline">LaTeX documentation</a>. </p> `, t.addEventListener("click", () => { n.classList.toggle("hidden"); const r = t.querySelector(".arrow"); r && (r.textContent = n.classList.contains("hidden") ? "▼" : "▲"); }), e.appendChild(t), e.appendChild(n), e; } createMathEditorContainer() { const e = a("math-editor-container mb-6"); e.appendChild(this.mathToolbar.getElement()); const t = d("Math Expression (LaTeX)", "math-expression"); return this.expressionInput = c( "Enter your math expression here...", "", (n) => this.handleInputChange(n) ), this.expressionInput.id = "math-editor-container mb-6", this.expressionInput.className = "math-input w-full p-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500", e.appendChild(t), e.appendChild(this.expressionInput), e; } handleInputChange(e) { this.expression = e, this.updatePreview(e); } createPreviewContainer() { return this.previewContainer = a( "preview-math-container h-64 bg-gray-50 rounded-lg flex items-center justify-center" ), this.previewContainer.innerHTML = '<div class="text-gray-400">Math preview will appear here</div>', this.previewContainer; } async updatePreview(e) { var r; const t = (r = this.popup.getElement()) == null ? void 0 : r.querySelector(".preview-math-container"); if (!t) return; const n = await this.renderer.renderMath(e, { width: 400, height: 100 }); t.innerHTML = "", t.appendChild(n); } async handleSubmit() { var t; const e = this.expression; if (e) { if ((t = this.editor) == null || t.ensureEditorFocus(), this.editingMath) { this.editingMath.setAttribute("data-math-expression", e); const n = await this.renderer.renderMath(e, { width: this.editingMath.clientWidth || 800, height: this.editingMath.clientHeight || 200 }); this.editingMath.innerHTML = "", this.editingMath.appendChild(n); } else { const n = a("math-container"); n.style.width = "100%", n.style.height = "200px", n.setAttribute("data-math-expression", e); const r = await this.renderer.renderMath(e, { width: n.clientWidth || 800, height: n.clientHeight || 200 }); n.appendChild(r), this.onInsert && this.onInsert(n); } this.popup.hide(); } } show(e) { this.editingMath = null, this.onInsert = e, this.popup.show(); } edit(e) { this.editingMath = e; const t = e.getAttribute("data-math-expression"); t && (this.expression = t, this.updatePreview(t)), this.popup.show(); } async redrawMath(e, t, n) { const r = await this.renderer.renderMath(t, n); e.innerHTML = "", e.appendChild(r); } destroy() { var e, t; this.popup.destroy(), this.mathToolbar.destroy(), (e = this.expressionInput) == null || e.remove(), (t = this.previewContainer) == null || t.remove(), this.editor = null, this.popup = null, this.renderer = null, this.onInsert = null, this.editingMath = null; } } export { b as MathMenu };