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
76 lines (75 loc) • 3.94 kB
JavaScript
/*! 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 c = (n, t, e) => t in n ? p(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
var s = (n, t, e) => c(n, typeof t != "symbol" ? t + "" : t, e);
/* empty css */
/* empty css */
import { createToolbarButton as m } from "../ToolbarPlugin/utils.mjs";
import g from "../../icons/anchor.svg.mjs";
import { PopupManager as f } from "../../core/ui/PopupManager.mjs";
class A {
constructor() {
s(this, "name", "anchor-links");
s(this, "editor", null);
s(this, "popup", null);
s(this, "savedCursor", null);
s(this, "toolbarButton", null);
s(this, "savedSelectedText", "");
}
initialize(t) {
this.editor = t, this.addToolbarButton(), this.popup = new f(t, {
title: t.t("Insert Anchor"),
className: "anchor-popup",
items: this.items(),
buttons: [
{ label: t.t("Cancel"), variant: "secondary", onClick: () => {
var e;
return (e = this.popup) == null ? void 0 : e.hide();
} },
{ label: t.t("Insert"), variant: "primary", onClick: () => this.insert() }
]
});
}
items() {
var t, e;
return [
{ type: "input", id: "anchor-id", label: ((t = this.editor) == null ? void 0 : t.t("Anchor ID")) || "Anchor ID" },
{ type: "input", id: "anchor-text", label: ((e = this.editor) == null ? void 0 : e.t("Text")) || "Text" }
];
}
addToolbarButton() {
var e, o;
const t = (e = this.editor) == null ? void 0 : e.getToolbar();
t && (this.toolbarButton = m({
icon: g,
title: (o = this.editor) == null ? void 0 : o.t("Insert Anchor"),
onClick: () => {
var r, a, h, l, d, u;
(r = this.editor) == null || r.ensureEditorFocus();
const i = (a = this.editor) == null ? void 0 : a.saveCursorPosition();
i && (this.savedCursor = i), this.savedSelectedText = ((d = (l = (h = this.editor) == null ? void 0 : h.getTextFormatter()) == null ? void 0 : l.getSelection()) == null ? void 0 : d.toString()) || "", (u = this.popup) == null || u.show();
}
}), t.appendChild(this.toolbarButton));
}
insert() {
var l;
if (!this.editor || !this.popup) return;
let t = String(this.popup.getValue("anchor-id") || "").trim();
const e = String(this.popup.getValue("anchor-text") || "").trim();
t || (t = this.slugify((this.savedSelectedText || "").trim() || "section")), this.savedCursor ? this.editor.restoreCursorPosition(this.savedCursor) : this.editor.ensureEditorFocus();
const o = (l = this.editor.getTextFormatter()) == null ? void 0 : l.getSelection(), i = o && o.rangeCount > 0 ? o.getRangeAt(0) : null, r = document.createElement("a");
r.id = t, r.href = `#${t}`, r.textContent = e || `#${t}`, r.className = "anchor-link";
const a = this.editor.getContainer(), h = !!i && a.contains(i.startContainer) && a.contains(i.endContainer);
i && h ? (i.insertNode(r), i.setStartAfter(r), i.collapse(!0), o == null || o.removeAllRanges(), o == null || o.addRange(i)) : this.editor.insertContent(r), this.popup.hide(), this.savedCursor = null, this.savedSelectedText = "";
}
slugify(t) {
return t.toLowerCase().trim().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-");
}
destroy() {
var t, e, o;
this.popup && (this.popup.destroy(), this.popup = null), this.toolbarButton && (this.toolbarButton.remove(), this.toolbarButton = null), (t = this.editor) == null || t.off("anchor-link"), (e = this.editor) == null || e.off("anchor-insert"), (o = this.editor) == null || o.off("anchor-error"), this.editor = null, this.savedCursor = null, this.savedSelectedText = "";
}
}
export {
A as AnchorLinkPlugin
};