Page MenuHomeSealhub

json-editor.stimulus.ts
No OneTemporary

json-editor.stimulus.ts

/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-call */
import { Controller } from "stimulus";
const JS_ID = "codemirror-js";
const JS_PATH = "/dist/codemirror.js";
const JS_MODE_ID = "codemirror-js-mode-js";
const JS_MODE_PATH = "/dist/codemirror-javascript-mode.js";
const CSS_ID = "codemirror-css";
const CSS_PATH = "/dist/codemirror.css";
declare const CodeMirror: any;
export default class JSONEditor extends Controller<HTMLTextAreaElement> {
cm: any;
saving = false;
addCSS() {
const tag = document.querySelector(`head #${CSS_ID}`);
if (!tag) {
const link = document.createElement("link");
link.setAttribute("rel", "stylesheet");
link.setAttribute("type", "text/css");
link.setAttribute("id", CSS_ID);
link.setAttribute("href", CSS_PATH);
document.head.appendChild(link);
}
}
async addJS(js_id: string, js_path: string) {
return new Promise<void>((resolve, reject) => {
const once_loaded = (e: MouseEvent) => {
(e.target as HTMLScriptElement).setAttribute("loaded", "true");
resolve();
};
try {
const tag = document.querySelector(`head #${js_id}`);
if (!tag) {
const script = document.createElement("script");
script.setAttribute("id", js_id);
script.setAttribute("src", js_path);
script.addEventListener("load", once_loaded);
document.head.appendChild(script);
} else {
if (tag.getAttribute("loaded") == "true") {
resolve();
} else {
tag.addEventListener("load", once_loaded);
}
}
} catch (e) {
reject(e);
}
});
}
async connect() {
if (this.element.parentNode?.querySelector(".CodeMirror")) {
//already loaded, quit;
return;
}
this.addCSS();
await this.addJS(JS_ID, JS_PATH);
await this.addJS(JS_MODE_ID, JS_MODE_PATH);
this.cm = CodeMirror.fromTextArea(this.element, {
mode: {
name: "javascript",
json: true,
},
theme: "default",
addModeClass: true,
lineWrapping: true,
});
this.cm.on("change", () => {
this.saving = true;
this.element.innerHTML = this.cm.getValue().replace("<", "&lt;");
this.saving = false;
});
// to prevent morhping from removing the element
this.cm.getWrapperElement().setAttribute("data-turbo-permanent", "");
const observer = new MutationObserver((mutation) => {
console.log("DETECTED TEXTAREA MUTATION CHANGE!", mutation);
if (!this.saving) {
if (this.cm.getValue() != this.element.innerHTML) {
console.log(
"SETTING CM VALUE TO",
this.element.innerHTML.slice(0, 100)
);
this.cm.setValue(this.element.innerHTML);
}
}
});
observer.observe(this.element, {
characterData: true,
subtree: true,
});
this.element.addEventListener("change", () => {
console.log("DETECTED TEXTAREA CHANGE!");
if (!this.saving) {
if (this.cm.getValue() != this.element.innerHTML) {
console.log(
"SETTING CM VALUE TO",
this.element.innerHTML.slice(0, 100)
);
this.cm.setValue(this.element.innerHTML);
}
}
});
this.element
.closest("details")
?.addEventListener("toggle", (event: MouseEvent) => {
if ((event.target as HTMLDetailsElement).open) {
this.cm.refresh();
}
});
}
async disconnect() {
console.log("DISCONNECTING JSON EDITOR");
}
}

File Metadata

Mime Type
text/x-java
Expires
Tue, Dec 24, 14:05 (13 m, 18 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
557328
Default Alt Text
json-editor.stimulus.ts (3 KB)

Event Timeline