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

218 lines (217 loc) 11.1 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 p = Object.defineProperty; var h = (d, e, t) => e in d ? p(d, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : d[e] = t; var r = (d, e, t) => h(d, typeof e != "symbol" ? e + "" : e, t); /* empty css */ /* empty css */ import { ResponsiveMenu as c } from "./components/ResponsiveMenu.mjs"; import { ViewportManager as u } from "./services/ViewportManager.mjs"; import v from "../../icons/desktop.svg.mjs"; import w from "../../icons/mobile.svg.mjs"; import m from "../../icons/responsive.svg.mjs"; import g from "../../icons/tablet.svg.mjs"; class H { constructor() { r(this, "name", "responsive"); r(this, "hotkeys", [ { keys: "Ctrl+1", description: "Mobile View", command: "responsive-mobile", icon: "📱" }, { keys: "Ctrl+2", description: "Tablet View", command: "responsive-tablet", icon: "📱" }, { keys: "Ctrl+3", description: "Desktop View", command: "responsive-desktop", icon: "💻" }, { keys: "Ctrl+4", description: "Large Desktop View", command: "responsive-large", icon: "💻" }, { keys: "Ctrl+5", description: "Ultra Wide View", command: "responsive-ultra", icon: "💻" }, { keys: "Ctrl+0", description: "Responsive View", command: "responsive-fluid", icon: "🔄" }, { keys: "Ctrl+Alt+R", description: "Responsive Menu", command: "responsive", icon: "🔄" } ]); r(this, "editor", null); r(this, "menu", null); r(this, "viewportManager"); r(this, "toolbarButton", null); r(this, "viewportIndicator", null); r(this, "resizeHandle", null); r(this, "isResizing", !1); r(this, "startX", 0); r(this, "startWidth", 0); r(this, "boundHotkeysKeydown"); r(this, "onResize", (e) => { if (!this.isResizing || !this.editor) return; const t = e.clientX - this.startX; let i = this.startWidth + t; i = Math.max(320, Math.min(i, 1920)); const s = this.editor.getContainer(); s.style.width = i + "px", s.style.maxWidth = i + "px", localStorage.setItem("responsive-custom-width", String(i)); }); r(this, "stopResize", (e) => { var t, i; this.isResizing && (this.isResizing = !1, document.body.style.cursor = "", (t = this.editor) == null || t.getDOMContext().removeEventListener("mousemove", this.onResize), (i = this.editor) == null || i.getDOMContext().removeEventListener("mouseup", this.stopResize)); }); this.viewportManager = new u(); } initialize(e) { this.menu = new c(e), this.editor = e, this.addViewportIndicator(), this.setupViewportControls(), this.setupHotkeys(), this.editor.on("responsive", () => { var t, i; (t = this.editor) == null || t.ensureEditorFocus(), (i = this.menu) == null || i.show(); }), this.editor.on("responsive-mobile", () => { this.setViewport("mobile"); }), this.editor.on("responsive-tablet", () => { this.setViewport("tablet"); }), this.editor.on("responsive-desktop", () => { this.setViewport("desktop"); }), this.editor.on("responsive-large", () => { this.setViewport("largeDesktop"); }), this.editor.on("responsive-ultra", () => { this.setViewport("ultraWide"); }), this.editor.on("responsive-fluid", () => { this.setViewport("responsive"); }); } addViewportIndicator() { var t, i, s; const e = (t = this.editor) == null ? void 0 : t.getToolbar(); e && (this.viewportIndicator = document.createElement("div"), this.viewportIndicator.className = "viewport-indicator flex items-center gap-2 px-3 py-1 bg-gray-100 rounded-lg text-sm font-medium text-gray-700 cursor-pointer hover:bg-gray-200 transition-colors", this.viewportIndicator.title = ((i = this.editor) == null ? void 0 : i.t("Current viewport - Click to change")) || "Current viewport - Click to change", this.updateViewportIndicator(), this.viewportIndicator.addEventListener("click", () => { var o; (o = this.menu) == null || o.show(); }), this.toolbarButton ? (s = this.toolbarButton.parentNode) == null || s.insertBefore( this.viewportIndicator, this.toolbarButton.nextSibling ) : e.appendChild(this.viewportIndicator)); } updateViewportIndicator() { if (!this.viewportIndicator) return; const e = this.viewportManager.getCurrentViewport(), t = this.viewportManager.getCurrentWidth(); let i = m; switch (e) { case "mobile": i = w; break; case "tablet": i = g; break; case "desktop": case "largeDesktop": case "ultraWide": i = v; break; } this.viewportIndicator.innerHTML = ` <span class="viewport-icon">${i}</span> <span class="viewport-label">${this.getViewportLabel(e)}</span> <span class="viewport-width text-xs text-gray-500">${t}px</span> `; } getViewportLabel(e) { var i, s, o, a, n, l; return { mobile: ((i = this.editor) == null ? void 0 : i.t("Mobile")) || "Mobile", tablet: ((s = this.editor) == null ? void 0 : s.t("Tablet")) || "Tablet", desktop: ((o = this.editor) == null ? void 0 : o.t("Desktop")) || "Desktop", largeDesktop: ((a = this.editor) == null ? void 0 : a.t("Large")) || "Large", ultraWide: ((n = this.editor) == null ? void 0 : n.t("Ultra")) || "Ultra", responsive: ((l = this.editor) == null ? void 0 : l.t("Fluid")) || "Fluid" }[e] || e; } setupViewportControls() { var i; if (!this.editor) return; const e = this.editor.getContainer(), t = this.viewportManager.getCurrentViewport(); this.viewportManager.setViewport(e, t), (i = this.menu) == null || i.onViewportChange((s) => { var o; this.viewportManager.setViewport(e, s), this.updateViewportIndicator(), (o = this.editor) == null || o.triggerEvent("viewportChanged", { viewport: s, width: this.viewportManager.getCurrentWidth() }), this.adaptTablesToViewport(s), this.removeResizeHandle(), s === "responsive" && (localStorage.removeItem("responsive-custom-width"), e.style.width = "100%", e.style.maxWidth = "none", setTimeout(() => { this.addResizeHandle(); }, 0)); }), this.viewportManager.onViewportChange((s, o) => { var a; if (this.updateViewportIndicator(), (a = this.editor) == null || a.triggerEvent("viewportChanged", { viewport: s, width: o }), this.adaptTablesToViewport(s), this.removeResizeHandle(), s === "responsive") { const n = localStorage.getItem("responsive-custom-width"); n && (e.style.width = n + "px", e.style.maxWidth = n + "px"), setTimeout(() => { this.addResizeHandle(); }, 0); } }), t === "responsive" && (localStorage.removeItem("responsive-custom-width"), e.style.width = "100%", e.style.maxWidth = "none", setTimeout(() => { this.addResizeHandle(); }, 0)); } adaptTablesToViewport(e) { if (!this.editor) return; this.editor.getContainer().querySelectorAll(".html-editor-table").forEach((s) => { const o = s; switch (o.classList.remove("responsive-table"), o.classList.remove( "breakpoint-320", "breakpoint-768", "breakpoint-1024", "breakpoint-1440", "breakpoint-1920" ), e) { case "mobile": o.classList.add("responsive-table", "breakpoint-320"); break; case "tablet": o.classList.add("responsive-table", "breakpoint-768"); break; case "desktop": o.classList.add("responsive-table", "breakpoint-1024"); break; case "largeDesktop": o.classList.add("responsive-table", "breakpoint-1440"); break; case "ultraWide": o.classList.add("responsive-table", "breakpoint-1920"); break; } }); } setupHotkeys() { var e; this.boundHotkeysKeydown = (t) => { var i, s; if (t.ctrlKey && !t.shiftKey && !t.altKey) { const o = t.key, a = { 1: "mobile", 2: "tablet", 3: "desktop", 4: "largeDesktop", 5: "ultraWide", 0: "responsive" }; if (a[o]) { t.preventDefault(); const n = (i = this.editor) == null ? void 0 : i.getContainer(); n && this.viewportManager.setViewport(n, a[o]); } } t.ctrlKey && (t.key === "ArrowLeft" || t.key === "ArrowRight") && (t.preventDefault(), (s = this.editor) != null && s.getContainer() && (t.key === "ArrowRight" ? this.viewportManager.nextViewport() : this.viewportManager.previousViewport())); }, (e = this.editor) == null || e.getDOMContext().addEventListener("keydown", this.boundHotkeysKeydown); } setViewport(e) { var i; const t = (i = this.editor) == null ? void 0 : i.getContainer(); t && this.viewportManager.setViewport(t, e); } getCurrentViewport() { return this.viewportManager.getCurrentViewport(); } getCurrentWidth() { return this.viewportManager.getCurrentWidth(); } addResizeHandle() { if (!this.editor) return; const e = this.editor.getContainer(); this.removeResizeHandle(), this.viewportManager.getCurrentViewport() === "responsive" && (e.style.position = "relative", this.resizeHandle = document.createElement("div"), this.resizeHandle.className = "html-editor-responsive-resize-handle", this.resizeHandle.title = this.editor.t("Resize editor width"), e.appendChild(this.resizeHandle), this.resizeHandle.addEventListener("mousedown", (t) => this.startResize(t))); } removeResizeHandle() { this.resizeHandle && this.resizeHandle.parentElement && this.resizeHandle.parentElement.removeChild(this.resizeHandle), this.resizeHandle = null; } startResize(e) { var t, i; this.editor && this.viewportManager.getCurrentViewport() === "responsive" && (this.isResizing = !0, this.startX = e.clientX, this.startWidth = this.editor.getContainer().offsetWidth, document.body.style.cursor = "ew-resize", (t = this.editor) == null || t.getDOMContext().addEventListener("mousemove", this.onResize), (i = this.editor) == null || i.getDOMContext().addEventListener("mouseup", this.stopResize)); } destroy() { var e, t; this.toolbarButton && this.toolbarButton.parentElement && this.toolbarButton.parentElement.removeChild(this.toolbarButton), this.viewportIndicator && this.viewportIndicator.parentElement && this.viewportIndicator.parentElement.removeChild(this.viewportIndicator), this.menu && (this.menu.destroy(), this.menu = null), this.viewportManager.destroy(), (e = this.editor) == null || e.off("responsive"), this.boundHotkeysKeydown && ((t = this.editor) == null || t.getDOMContext().removeEventListener("keydown", this.boundHotkeysKeydown), this.boundHotkeysKeydown = void 0), this.editor = null, this.toolbarButton = null, this.viewportIndicator = null, this.removeResizeHandle(); } } export { H as ResponsivePlugin };