|
// retoor <retoor@molodetz.nl>
|
|
|
|
import { CodeMirrorModes } from "./codemirrorModes.js";
|
|
|
|
class GistEditor {
|
|
constructor(textareaId, langSelectId) {
|
|
this.editor = null;
|
|
this.initialized = false;
|
|
this.textareaId = textareaId || "gist-source-editor";
|
|
this.langSelectId = langSelectId || "gist-language";
|
|
this.maxLength = 400000;
|
|
}
|
|
|
|
init() {
|
|
if (this.initialized) return;
|
|
if (typeof CodeMirror === "undefined") return;
|
|
|
|
const textarea = document.getElementById(this.textareaId);
|
|
if (!textarea) return;
|
|
this.initialized = true;
|
|
|
|
this.editor = CodeMirror.fromTextArea(textarea, {
|
|
lineNumbers: true,
|
|
mode: textarea.dataset.language || "plaintext",
|
|
theme: "monokai",
|
|
indentUnit: 4,
|
|
tabSize: 4,
|
|
lineWrapping: true,
|
|
extraKeys: {
|
|
"Ctrl-S": () => {
|
|
const form = textarea.closest("form");
|
|
if (form) {
|
|
this.editor.save();
|
|
form.submit();
|
|
}
|
|
},
|
|
},
|
|
});
|
|
|
|
this.editor.setSize(null, 400);
|
|
|
|
const langSelect = document.getElementById(this.langSelectId);
|
|
if (langSelect) {
|
|
langSelect.addEventListener("change", () => {
|
|
const mode = langSelect.value;
|
|
this.editor.setOption("mode", CodeMirrorModes.LANGUAGE_MODES[mode] || mode);
|
|
});
|
|
}
|
|
|
|
const form = textarea.closest("form");
|
|
if (form) {
|
|
form.addEventListener("submit", (event) => {
|
|
this.editor.save();
|
|
if (textarea.value.length > this.maxLength) {
|
|
event.preventDefault();
|
|
this.showLengthError(textarea);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
showLengthError(textarea) {
|
|
const field = textarea.closest(".auth-field");
|
|
const target = field || textarea.parentElement;
|
|
let message = target.querySelector(".gist-length-error");
|
|
if (!message) {
|
|
message = document.createElement("div");
|
|
message.className = "gist-length-error";
|
|
target.appendChild(message);
|
|
}
|
|
const length = textarea.value.length.toLocaleString();
|
|
const limit = this.maxLength.toLocaleString();
|
|
message.textContent = `Source code is ${length} characters; the maximum is ${limit}.`;
|
|
}
|
|
|
|
refresh() {
|
|
if (this.editor) {
|
|
setTimeout(() => this.editor.refresh(), 100);
|
|
}
|
|
}
|
|
}
|
|
window.GistEditor = GistEditor;
|