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

161 lines (160 loc) 6.63 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 f = (m, t, e) => t in m ? p(m, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : m[t] = e; var a = (m, t, e) => f(m, typeof t != "symbol" ? t + "" : t, e); /* empty css */ /* empty css */ import { TimerMenu as T } from "./components/TimerMenu.mjs"; import { TimerManager as g } from "./services/TimerManager.mjs"; import { createToolbarButton as w } from "../ToolbarPlugin/utils.mjs"; import b from "../../icons/timer.svg.mjs"; import { TimerContextMenu as y } from "./components/TimerContextMenu.mjs"; import { createLineBreak as E } from "../../utils/helpers.mjs"; class A { constructor() { a(this, "name", "timer"); a(this, "hotkeys", [{ keys: "Ctrl+Alt+D", description: "Insert timer", command: "timer", icon: "⏱️" }]); a(this, "editor", null); a(this, "menu", null); a(this, "manager"); a(this, "toolbarButton", null); a(this, "contextMenu", null); } initialize(t) { this.editor = t, this.manager = new g(t), this.menu = new T(this.manager, t), this.contextMenu = new y(this.manager, t), this.addToolbarButton(), this.setupEventListeners(), this.startTimerUpdates(), t.on("timer", () => this.showTimerMenu()); } addToolbarButton() { var e; if (!this.editor) return; const t = (e = this.editor) == null ? void 0 : e.getToolbar(); t && (this.toolbarButton = w({ icon: b, title: this.editor.t("Timer"), onClick: () => this.showTimerMenu() }), t.appendChild(this.toolbarButton)); } setupEventListeners() { this.editor && (this.editor.getContainer().addEventListener("click", (t) => this.handleTimerClick(t)), this.editor.getContainer().addEventListener("contextmenu", (t) => this.handleContextMenu(t))); } handleTimerClick(t) { var n; const i = t.target.closest(".timer-widget"); if (!i) return; const r = i.getAttribute("data-timer-id"); if (!r) return; const o = this.manager.getTimer(r); o && ((n = this.menu) == null || n.showEditTimerForm(o)); } handleContextMenu(t) { var n; const i = t.target.closest(".timer-widget"); if (!i) return; t.preventDefault(); const r = i.getAttribute("data-timer-id"); if (!r) return; const o = this.manager.getTimer(r); o && ((n = this.contextMenu) == null || n.show(t, o, (s) => { this.handleContextMenuAction(s, o); })); } handleContextMenuAction(t, e) { var i, r, o, n, s; switch (t) { case "edit-timer": (i = this.menu) == null || i.showEditTimerForm(e); break; case "copy-timer": try { this.manager.copyTimer(e.id), (o = this.editor) == null || o.showSuccessNotification( ((r = this.editor) == null ? void 0 : r.t("Timer copied successfully")) || "Timer copied successfully" ), this.refreshTimers(); } catch { (s = this.editor) == null || s.showErrorNotification( ((n = this.editor) == null ? void 0 : n.t("Failed to copy timer")) || "Failed to copy timer" ); } break; case "export-timer": this.showExportDialog(e); break; case "import-timer": this.showImportDialog(); break; case "delete-timer": this.manager.deleteTimer(e.id), this.refreshTimers(); break; } } showTimerMenu() { var e; if (!this.editor) return; const t = this.editor.saveCursorPosition(); (e = this.menu) == null || e.show((i) => { this.editor && (t && this.editor.restoreCursorPosition(t), this.insertTimer(i)); }); } insertTimer(t) { if (!this.editor) return; const e = this.manager.generateTimerHTML(t); this.editor.insertContent(e), this.editor.insertContent(E()); } refreshTimers() { var e; const t = (e = this.editor) == null ? void 0 : e.getContainer().querySelectorAll(".timer-widget"); t == null || t.forEach((i) => { const r = i.getAttribute("data-timer-id"); if (!r) return; const o = this.manager.getTimer(r); if (!o) return; const n = this.manager.generateTimerHTML(o), s = document.createElement("div"); s.innerHTML = n; const c = s.firstElementChild, h = s.querySelector("script"); if (c && i.parentNode) { const d = i.parentNode.querySelector(`script[data-timer-id="${r}"]`); d && d.remove(), i.parentNode && i.parentNode.replaceChild(c, i), h && i.parentNode && (h.setAttribute("data-timer-id", r), i.parentNode.appendChild(h)); } }); } startTimerUpdates() { setInterval(() => { this.refreshTimers(); }, 1e3); } showExportDialog(t) { var e; try { const i = JSON.stringify(t, null, 2), r = new Blob([i], { type: "application/json" }), o = URL.createObjectURL(r), n = document.createElement("a"); n.href = o, n.download = `timer-${t.id}.json`, n.click(), URL.revokeObjectURL(o); } catch { (e = this.editor) == null || e.showErrorNotification(this.editor.t("Export failed") || "Export failed"); } } showImportDialog() { const t = document.createElement("input"); t.type = "file", t.accept = ".json", t.onchange = (e) => { var r; const i = (r = e.target.files) == null ? void 0 : r[0]; if (i) { const o = new FileReader(); o.onload = (n) => { var s, c, h, d, l; try { const u = JSON.parse((s = n.target) == null ? void 0 : s.result); this.manager.importTimer(u), (h = this.editor) == null || h.showSuccessNotification( ((c = this.editor) == null ? void 0 : c.t("Timer imported successfully")) || "Timer imported successfully" ), this.refreshTimers(); } catch { (l = this.editor) == null || l.showErrorNotification(((d = this.editor) == null ? void 0 : d.t("Import failed")) || "Import failed"); } }, o.readAsText(i); } }, t.click(); } destroy() { var t; this.toolbarButton && this.toolbarButton.parentElement && this.toolbarButton.parentElement.removeChild(this.toolbarButton), this.menu && (this.menu.destroy(), this.menu = null), this.contextMenu && (this.contextMenu.destroy(), this.contextMenu = null), (t = this.editor) == null || t.off("timer"), this.editor = null, this.manager = null, this.toolbarButton = null; } } export { A as TimerPlugin };