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
98 lines (97 loc) • 3.78 kB
JavaScript
var l = Object.defineProperty;
var r = (n, t, e) => t in n ? l(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
var i = (n, t, e) => r(n, typeof t != "symbol" ? t + "" : t, e);
/* empty css */
/* empty css */
import { BlockContextMenu as a } from "./components/BlockContextMenu.mjs";
import { BlockCommand as h } from "./commands/BlockCommand.mjs";
import { createToolbarButton as d } from "../ToolbarPlugin/utils.mjs";
import u from "../../icons/block.svg.mjs";
import { Resizer as k } from "../../utils/Resizer.mjs";
class M {
constructor() {
i(this, "name", "block");
i(this, "hotkeys", [{ keys: "Ctrl+Alt+B", description: "Insert block", command: "block", icon: "🧱" }]);
i(this, "editor", null);
i(this, "contextMenu", null);
i(this, "activeBlock", null);
i(this, "currentResizer", null);
}
initialize(t) {
this.contextMenu = new a(t), this.editor = t, this.addToolbarButton(), this.setupBlockEvents(), this.editor.on("block", () => {
this.insertBlock();
});
}
addToolbarButton() {
const t = document.querySelector(".editor-toolbar");
if (!t) return;
const e = d({
icon: u,
title: "Insert Block",
onClick: () => this.insertBlock()
});
t.appendChild(e);
}
setupBlockEvents() {
if (!this.editor) return;
const t = this.editor.getContainer();
this.handleBlockClick = this.handleBlockClick.bind(this), this.handleContextMenu = this.handleContextMenu.bind(this), t.addEventListener("click", this.handleBlockClick), t.addEventListener("contextmenu", this.handleContextMenu);
}
handleBlockClick(t) {
if (!this.editor) return;
const e = t.target.closest(".editor-block");
if (e instanceof HTMLElement) {
this.activeBlock !== e && (this.deactivateBlock(), this.activateBlock(e)), this.currentResizer && (this.currentResizer.destroy(), this.currentResizer = null), this.currentResizer = new k(e, {
handleSize: 10,
handleColor: "blue",
onResizeStart: () => {
var o;
return (o = this.editor) == null ? void 0 : o.disableObserver();
},
onResize: (o, s) => console.log(`Resized to ${o}x${s}`),
onResizeEnd: () => {
var o;
return (o = this.editor) == null ? void 0 : o.enableObserver();
}
});
const c = e.querySelector(".block-content");
c && c.focus();
} else
this.deactivateBlock();
}
handleContextMenu(t) {
var c;
const e = t.target.closest(".editor-block");
if (e instanceof HTMLElement) {
t.preventDefault();
const o = t.clientX + window.scrollX, s = t.clientY + window.scrollY;
console.log("Mouse coordinates with scroll:", o, s), (c = this.contextMenu) == null || c.show(e, o, s);
}
}
activateBlock(t) {
this.activeBlock = t, t.classList.add("active"), t.focus();
}
deactivateBlock() {
if (this.activeBlock) {
this.activeBlock.classList.remove("active");
const t = this.activeBlock.querySelector(".block-content");
t && (t.contentEditable = "false");
}
this.activeBlock = null;
}
insertBlock() {
if (!this.editor) return;
new h(this.editor).execute();
}
destroy() {
var t;
if (this.editor) {
const e = this.editor.getContainer();
e.removeEventListener("click", this.handleBlockClick), e.removeEventListener("contextmenu", this.handleContextMenu);
}
(t = this.editor) == null || t.off("block"), this.currentResizer && (this.currentResizer.destroy(), this.currentResizer = null), this.contextMenu && (this.contextMenu.destroy(), this.contextMenu = null), this.deactivateBlock(), this.editor = null, this.activeBlock = null;
}
}
export {
M as BlockPlugin
};