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

143 lines (142 loc) 7.56 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 L = Object.defineProperty; var C = (h, t, e) => t in h ? L(h, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : h[t] = e; var c = (h, t, e) => C(h, typeof t != "symbol" ? t + "" : t, e); /* empty css */ /* empty css */ import { createToolbarButton as E } from "../ToolbarPlugin/utils.mjs"; import N from "../../icons/list-bullet.svg.mjs"; import B from "../../icons/list-numbered.svg.mjs"; import { createP as y } from "../../utils/helpers.mjs"; class b { // private menu: ListsMenu; 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", (t) => { (t.metaKey || t.ctrlKey) && t.key === "Enter" && (t.preventDefault(), this.exitListAndInsertBreak()); }); } initialize(t) { this.editor = t, this.addToolbarButtons(), this.setupListHandling(), this.editor.on("lists-unordered", () => { var e; (e = this.editor) == null || e.ensureEditorFocus(), this.toggleList("unordered"); }), this.editor.on("lists-ordered", () => { var e; (e = this.editor) == null || e.ensureEditorFocus(), this.toggleList("ordered"); }); } addToolbarButtons() { var e, o, i, n; const t = (e = this.editor) == null ? void 0 : e.getToolbar(); t && (this.ulButton = E({ icon: N, 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 = E({ icon: B, 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(); } }), t.appendChild(this.ulButton), t.appendChild(this.olButton), (n = this.editor) == null || n.on("selectionchange", () => this.handleSelectionChange())); } handleSelectionChange() { var n, s, r, d, a, l, m, g, u; const t = (s = (n = this.editor) == null ? void 0 : n.getTextFormatter()) == null ? void 0 : s.getSelection(); if (!t || !t.rangeCount) return; const o = t.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"), (u = this.olButton) == null || u.classList.remove("active")); } setupListHandling() { this.editor && this.editor.getContainer().addEventListener("keydown", this.handleKeydown); } exitListAndInsertBreak() { var i, n, s, r, d; const t = (n = (i = this.editor) == null ? void 0 : i.getTextFormatter()) == null ? void 0 : n.getSelection(); if (!t || !t.rangeCount) return; const e = t.getRangeAt(0), o = (s = e.commonAncestorContainer.parentElement) == null ? void 0 : s.closest("li"); if (o) { const a = o.parentElement; if (!a) return; const l = y("my-4"); a.nextSibling ? (r = a.parentNode) == null || r.insertBefore(l, a.nextSibling) : (d = a.parentNode) == null || d.appendChild(l), e.selectNodeContents(l), e.collapse(!0), t.removeAllRanges(), t.addRange(e); } } toggleList(t) { var s, r; if (!this.editor) return; const e = (s = this.editor.getTextFormatter()) == null ? void 0 : s.getSelection(); if (!e || !e.rangeCount) return; const o = e.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 ? t === "ordered" && n.tagName === "OL" || t === "unordered" && n.tagName === "UL" ? this.unwrapList(n) : this.replaceList(n, t) : this.createNewList(o, t); } unwrapList(t) { var s, r, d; const e = Array.from(t.querySelectorAll("li")), o = document.createElement("div"); e.forEach((a, l) => { o.appendChild(document.createTextNode(a.textContent || "")), l < e.length - 1 && o.appendChild(document.createElement("br")); }), (s = t.parentNode) == null || s.replaceChild(o, t); 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(t, e) { var n; const o = e === "ordered" ? "ol" : "ul", i = document.createElement(o); Array.from(t.children).forEach((s) => { const r = document.createElement("li"); r.innerHTML = s.innerHTML, i.appendChild(r); }), (n = t.parentNode) == null || n.replaceChild(i, t), this.applyListStyles(i, e); } createNewList(t, e) { var d, a; const o = t.extractContents(), i = e === "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 u = document.createElement("li"); u.appendChild(l.cloneNode(!0)), n.appendChild(u); } } }), n.children.length === 0) { const l = document.createElement("li"); l.textContent = "List item", n.appendChild(l); } t.insertNode(n), this.applyListStyles(n, e); 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(t, e) { e === "ordered" ? t.className = "list-decimal pl-8 my-4 space-y-2" : t.className = "list-disc pl-8 my-4 space-y-2", t.querySelectorAll("li").forEach((o) => { o.className = "pl-2"; }); } destroy() { var t, e; 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), (t = this.editor) == null || t.off("selectionchange"), (e = this.editor) == null || e.off("lists"), this.editor = null, this.ulButton = null, this.olButton = null; } } export { b as ListsPlugin };