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
84 lines (83 loc) • 3.67 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 l = Object.defineProperty;
var a = (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) => a(n, typeof t != "symbol" ? t + "" : t, e);
import "./style.scss.mjs";
import "./public.scss.mjs";
import { VideoUploader as c } from "./services/VideoUploader.mjs";
import { VideoContextMenu as h } from "./components/VideoContextMenu.mjs";
import { ResizableElement as u } from "../../utils/ResizableElement.mjs";
import { createToolbarButton as m } from "../ToolbarPlugin/utils.mjs";
import { VideoCommand as d } from "./commands/VideoCommand.mjs";
import p from "../../icons/video.svg.mjs";
class B {
constructor() {
i(this, "name", "video");
i(this, "hotkeys", [{ keys: "Ctrl+Alt+V", description: "Insert video", command: "video", icon: "🎥" }]);
i(this, "editor", null);
i(this, "toolbarButton", null);
i(this, "uploader");
i(this, "contextMenu", null);
i(this, "resizer");
i(this, "handleContextMenu", (t) => {
var o;
const e = t.target.closest("video");
if (e instanceof HTMLVideoElement) {
t.preventDefault();
const r = t.clientX, s = t.clientY;
console.log("Mouse coordinates with scroll:", r, s), (o = this.contextMenu) == null || o.show(e, r, s);
}
});
i(this, "handleClick", (t) => {
const e = t.target.closest("video");
e instanceof HTMLVideoElement ? this.resizer.attachTo(e) : this.resizer.detach();
});
this.uploader = new c(), this.resizer = new u();
}
initialize(t) {
this.contextMenu = new h(t), this.editor = t, this.addToolbarButton(), this.setupVideoEvents(), this.editor.on("video", () => {
this.handleVideoUpload();
});
}
addToolbarButton() {
var e, o;
const t = (e = this.editor) == null ? void 0 : e.getToolbar();
t && (this.toolbarButton = m({
icon: p,
title: (o = this.editor) == null ? void 0 : o.t("Insert Video"),
onClick: () => this.handleVideoUpload()
}), t.appendChild(this.toolbarButton));
}
setupVideoEvents() {
if (!this.editor) return;
const t = this.editor.getContainer();
t.addEventListener("contextmenu", this.handleContextMenu), t.addEventListener("click", this.handleClick), this.editor.on("file-drop", (e) => {
var o;
e.type.startsWith("video/") && ((o = this.editor) == null || o.ensureEditorFocus(), new d(this.editor, e.content).execute());
});
}
async handleVideoUpload(t) {
if (this.editor) {
this.editor.ensureEditorFocus();
try {
const e = t || await this.uploader.selectFile();
if (!e) return;
const o = await this.uploader.readFileAsDataUrl(e);
new d(this.editor, o).execute();
} catch (e) {
console.error("Failed to upload video:", e);
}
}
}
destroy() {
var t, e;
if (this.editor) {
const o = this.editor.getContainer();
o.removeEventListener("contextmenu", this.handleContextMenu), o.removeEventListener("click", this.handleClick);
}
this.contextMenu && (this.contextMenu.destroy(), this.contextMenu = null), this.toolbarButton && (this.toolbarButton.remove(), this.toolbarButton = null), (t = this.editor) == null || t.off("video"), (e = this.editor) == null || e.off("file-drop"), this.resizer.detach(), this.editor = null, this.uploader = null, this.resizer = null;
}
}
export {
B as VideoPlugin
};