50 lines
1.4 KiB
JavaScript
50 lines
1.4 KiB
JavaScript
|
import "../vendor/ace/ace.js";
|
||
|
import { findNearestParent } from "./node-utils.mjs";
|
||
|
|
||
|
export default class Editor {
|
||
|
/**
|
||
|
* Create a new editor
|
||
|
* @param {string} elementID ID of element to replace with the editor
|
||
|
* @param {boolean} [hookForm=true] Automatically add event to parent form (if any) to set the value on submit
|
||
|
*/
|
||
|
constructor(elementID, hookForm = true) {
|
||
|
/** @type {string} */
|
||
|
let originalElementName = null;
|
||
|
|
||
|
/** @type {HTMLFormElement} */
|
||
|
let parentForm = null;
|
||
|
|
||
|
if (hookForm) {
|
||
|
const el = document.getElementById(elementID);
|
||
|
if (!el) {
|
||
|
throw new Error("there is no element with the specified ID");
|
||
|
}
|
||
|
|
||
|
originalElementName = el.getAttribute("name");
|
||
|
if (originalElementName) {
|
||
|
// If it has a name it might have a form for a parent
|
||
|
parentForm = findNearestParent(el, (parent) => parent.tagName == "FORM");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Create editor
|
||
|
ace.config.set('basePath', '/static/vendor/ace')
|
||
|
this.editor = ace.edit(elementID);
|
||
|
|
||
|
// todo make this stuff customizable??
|
||
|
this.editor.setTheme("ace/theme/dracula");
|
||
|
this.editor.setOptions({
|
||
|
fontFamily: "Iosevka Web",
|
||
|
fontSize: "12pt",
|
||
|
});
|
||
|
this.editor.getSession().setUseWrapMode(true);
|
||
|
this.editor.setKeyboardHandler("ace/keyboard/vim");
|
||
|
this.editor.session.setMode("ace/mode/nix");
|
||
|
|
||
|
if (parentForm !== null) {
|
||
|
parentForm.addEventListener("formdata", (ev) => {
|
||
|
ev.formData.set(originalElementName, this.editor.getValue());
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
}
|