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

288 lines (287 loc) 8.65 kB
var y = Object.defineProperty; var C = (p, t, e) => t in p ? y(p, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : p[t] = e; var d = (p, t, e) => C(p, typeof t != "symbol" ? t + "" : t, e); /* empty css */ /* empty css */ import { createToolbarButton as I } from "../ToolbarPlugin/utils.mjs"; import { PopupManager as A } from "../../core/ui/PopupManager.mjs"; import { createContainer as u, createButton as h, createInputField as T } from "../../utils/helpers.mjs"; import B from "../../icons/style.svg.mjs"; import { AVAILABLE_STYLES as S } from "./constants.mjs"; class P { constructor() { d(this, "name", "block-style"); d(this, "editor", null); d(this, "toolbarButton", null); d(this, "popup", null); d(this, "selectedElement", null); } initialize(t) { this.editor = t, this.popup = new A(t, { title: t.t("Block Style Editor"), className: "block-style-editor", closeOnClickOutside: !0, items: this.createPopupItems(), buttons: [ { label: t.t("Apply"), variant: "primary", onClick: () => this.applyStyles() }, { label: t.t("Cancel"), variant: "secondary", onClick: () => { var e; return (e = this.popup) == null ? void 0 : e.hide(); } } ] }), this.addToolbarButton(), this.editor.on("selectionchange", () => this.handleSelectionChange()); } addToolbarButton() { var e; const t = document.querySelector(".editor-toolbar"); t && (this.toolbarButton = I({ icon: B, title: (e = this.editor) == null ? void 0 : e.t("Block Style"), onClick: () => this.showPopup() }), t.appendChild(this.toolbarButton)); } handleSelectionChange() { var i, o, n, l; const t = window.getSelection(); if (!t || t.rangeCount === 0) return; const s = t.getRangeAt(0).commonAncestorContainer.parentElement; if (this.editor) { if (s === ((i = this.editor) == null ? void 0 : i.getContainer())) { this.selectedElement = null, (o = this.toolbarButton) == null || o.classList.remove("active"); return; } s && this.isBlockElement(s) ? (this.selectedElement = s, (n = this.toolbarButton) == null || n.classList.add("active")) : (this.selectedElement = null, (l = this.toolbarButton) == null || l.classList.remove("active")); } } isBlockElement(t) { 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(t.tagName); } createPopupItems() { return [ { type: "custom", id: "style-editor", content: () => this.createStyleEditor() }, { type: "custom", id: "class-editor", content: () => this.createClassEditor() } ]; } createStyleEditor() { var n, l, a; const t = u("popup-item"), e = document.createElement("label"); e.textContent = ((n = this.editor) == null ? void 0 : n.t("Inline Styles")) || "Inline Styles", t.appendChild(e); const s = u("style-list"); (((a = (l = this.selectedElement) == null ? void 0 : l.getAttribute("style")) == null ? void 0 : a.split(";")) || []).forEach((c) => { if (c.trim()) { const [r, m] = c.split(":").map((E) => E.trim()); if (r && m) { const E = this.createStyleItem(r, m); s.appendChild(E); } } }); const o = h("Add Style", () => this.addStyle(s)); return o.className = "add-button", t.appendChild(s), t.appendChild(o), t; } createStyleItem(t, e) { const s = u("style-item"), i = document.createElement("select"); i.className = "style-property-select", Object.keys(S).forEach((l) => { const a = document.createElement("option"); a.value = l, a.textContent = l, a.selected = l === t, i.appendChild(a); }); const o = document.createElement("select"); o.className = "style-value-select", i.addEventListener("change", () => { this.updateValueSelect(o, i.value); }), this.updateValueSelect(o, i.value, e); const n = h("×", () => s.remove()); return n.className = "remove-button", s.appendChild(i), s.appendChild(o), s.appendChild(n), s; } /** * Обновляет выпадающий список значений в зависимости от выбранного свойства. */ updateValueSelect(t, e, s = "") { t.innerHTML = "", (S[e] || []).forEach((o) => { const n = document.createElement("option"); n.value = o, n.textContent = o, n.selected = o === s, t.appendChild(n); }); } addStyle(t) { const e = this.createStyleItem("", ""); t.appendChild(e); } createClassEditor() { var n, l, a; const t = u("popup-item"), e = document.createElement("label"); e.textContent = ((n = this.editor) == null ? void 0 : n.t("CSS Classes")) || "CSS Classes", t.appendChild(e); const s = u("class-list"); (((a = (l = this.selectedElement) == null ? void 0 : l.getAttribute("class")) == null ? void 0 : a.split(" ")) || []).forEach((c) => { if (c.trim()) { const r = this.createClassItem(c); s.appendChild(r); } }); const o = h("Add Class", () => this.addClass(s)); return o.className = "add-button", t.appendChild(s), t.appendChild(o), t; } createClassItem(t) { const e = u("class-item"), s = T("text", "Enter class (e.g., my-class)", t); s.className = "class-input"; const i = h("×", () => e.remove()); return i.className = "remove-button", e.appendChild(s), e.appendChild(i), e; } addClass(t) { const e = this.createClassItem(""); t.appendChild(e); } showPopup() { if (!this.selectedElement || !this.popup) return; const t = document.createElement("div"), e = this.createStyleEditor(), s = this.createClassEditor(); t.appendChild(e), t.appendChild(s), this.popup.setContent(t), this.popup.show(); } applyStyles() { var s, i, o; if (!this.selectedElement || !this.popup) return; (s = this.editor) == null || s.ensureEditorFocus(); const t = (i = this.popup.getElement()) == null ? void 0 : i.querySelector(".style-list"), e = (o = this.popup.getElement()) == null ? void 0 : o.querySelector(".class-list"); if (t) { const n = Array.from(t.querySelectorAll(".style-item")).map((l) => { const a = l.querySelector(".style-property-select"), c = l.querySelector(".style-value-select"), r = a.value.trim(), m = c.value.trim(); return r && m ? `${r}: ${m}` : ""; }).filter((l) => l).join("; "); this.selectedElement.setAttribute("style", n); } if (e) { const n = Array.from(e.querySelectorAll(".class-input")).map((l) => l.value.trim()).filter((l) => l).join(" "); this.selectedElement.setAttribute("class", n); } this.popup.hide(); } destroy() { var t, e, s; (t = this.toolbarButton) == null || t.remove(), this.toolbarButton = null, (e = this.editor) == null || e.off("selectionchange"), (s = this.popup) == null || s.destroy(), this.popup = null, this.editor = null; } } export { P as BlockStylePlugin };