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
129 lines (128 loc) • 4.56 kB
JavaScript
var s = Object.defineProperty;
var c = (r, t, e) => t in r ? s(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
var i = (r, t, e) => c(r, typeof t != "symbol" ? t + "" : t, e);
/* empty css */
/* empty css */
import { LinkMenu as u } from "./components/LinkMenu.mjs";
import { createToolbarButton as h } from "../ToolbarPlugin/utils.mjs";
import a from "../../icons/delete.svg.mjs";
import d from "../../icons/edit.svg.mjs";
import m from "../../icons/link.svg.mjs";
import { ContextMenu as f } from "../../core/ui/ContextMenu.mjs";
import { createLink as g } from "../../utils/helpers.mjs";
class v {
constructor() {
i(this, "name", "link");
i(this, "hotkeys", [{ keys: "Ctrl+Alt+K", description: "Insert link", command: "link", icon: "🔗" }]);
i(this, "editor", null);
i(this, "menu", null);
i(this, "contextMenu", null);
i(this, "currentRange", null);
i(this, "toolbarButton", null);
i(this, "handleContextMenu", (t) => {
var n;
const e = t.target.closest("a");
if (e instanceof HTMLAnchorElement) {
t.preventDefault();
const o = t.clientX + window.scrollX, l = t.clientY + window.scrollY;
console.log("Mouse coordinates with scroll:", o, l), (n = this.contextMenu) == null || n.show(e, o, l);
}
});
}
initialize(t) {
var e, n;
this.menu = new u(t), this.contextMenu = new f(
t,
[
{
label: (e = this.editor) == null ? void 0 : e.t("Edit"),
icon: d,
iconPosition: "right",
hotkey: "S",
onClick: (o) => {
o && this.editLink(o);
}
},
{
type: "divider"
},
{
label: (n = this.editor) == null ? void 0 : n.t("Remove"),
icon: a,
iconPosition: "right",
hotkey: "D",
onClick: (o) => {
o && this.removeLink(o);
}
}
],
{
orientation: "horizontal"
}
), this.editor = t, this.addToolbarButton(), this.setupContextMenu(), this.editor.on("link", () => {
this.openModal();
});
}
addToolbarButton() {
var e;
const t = document.querySelector(".editor-toolbar");
t && (this.toolbarButton = h({
icon: m,
title: (e = this.editor) == null ? void 0 : e.t("Insert Link"),
onClick: () => {
this.openModal();
}
}), t.appendChild(this.toolbarButton));
}
setupContextMenu() {
if (!this.editor) return;
this.editor.getContainer().addEventListener("contextmenu", this.handleContextMenu);
}
openModal() {
var n, o;
if (!this.editor) return;
(n = this.editor) == null || n.ensureEditorFocus();
const t = window.getSelection();
t && t.rangeCount > 0 && (this.currentRange = t.getRangeAt(0).cloneRange());
const e = t ? t.toString().trim() : "";
(o = this.menu) == null || o.show(
(l) => {
this.handleLinkInsertion(l, e);
},
{ anchor: e }
);
}
handleLinkInsertion(t, e) {
if (!this.editor || !this.currentRange) return;
const n = t.anchor || e, o = g(n, t.url);
t.title && (o.title = t.title), t.nofollow && (o.rel = "nofollow"), t.targetBlank && (o.target = "_blank"), this.currentRange.deleteContents(), this.currentRange.insertNode(o), this.currentRange.collapse(!1), this.currentRange = null;
}
editLink(t) {
var n;
if (!this.editor) return;
const e = {
url: t.href,
anchor: t.textContent || "",
title: t.title,
nofollow: t.rel.includes("nofollow"),
targetBlank: t.target === "_blank"
};
(n = this.menu) == null || n.show((o) => {
t.href = o.url, t.textContent = o.anchor || o.url, t.title = o.title || "", t.rel = o.nofollow ? "nofollow" : "", t.target = o.targetBlank ? "_blank" : "";
}, e);
}
removeLink(t) {
if (!this.editor) return;
const e = document.createTextNode(t.textContent || "");
t.replaceWith(e);
}
destroy() {
var e, n;
(e = this.editor) == null || e.off("link"), this.contextMenu && (this.contextMenu.destroy(), this.contextMenu = null), this.toolbarButton && this.toolbarButton.parentElement && (this.toolbarButton.parentElement.removeChild(this.toolbarButton), this.toolbarButton = null);
const t = (n = this.editor) == null ? void 0 : n.getContainer();
t && t.removeEventListener("contextmenu", this.handleContextMenu), this.menu = null, this.editor = null, this.currentRange = null;
}
}
export {
v as LinkPlugin
};