import FocusEditorCore from "./FocusEditorCore.mjs";
import { debounce } from "./helper.mjs";
/** FocusEditorWebComponent replaces a given HTML element with a editable foxus editor element */
class FocusEditorWebComponent extends HTMLElement {
static observedAttributes = [
"scroll",
"name",
"tab-size",
"buttons",
"placeholder",
"autofocus",
"readonly",
];
editor = null;
constructor() {
super();
function removeLeadingWhitespaces(text) {
text = text.replace(/\r/g, "\n");
const firstLine = text.split("\n").filter((t) => t.length > 0)[0];
const initialSpace = firstLine
? firstLine.match(/^\s+/)
? firstLine.match(/^\s+/)[0]?.length
: 0
: 0;
if (initialSpace === 0) {
return text;
}
return text
.split("\n")
.map((l) => l.replace(new RegExp(`^\\s{${initialSpace}}`), ""))
.join("\n");
}
const div = document.createElement("div");
let text =
this.getAttribute("value") ||
removeLeadingWhitespaces(this.textContent.replace(/\n\s+$/, ""));
if (
this.childElementCount &&
this.firstElementChild.tagName === "TEXTAREA"
) {
this.classList.add("textarea");
if (
!this.getAttribute("name") &&
this.firstElementChild.getAttribute("name")
) {
this.setAttribute("name", this.firstElementChild.getAttribute("name"));
}
if (
!this.getAttribute("id") &&
this.firstElementChild.getAttribute("id") !== null
) {
this.setAttribute("id", this.firstElementChild.getAttribute("id"));
}
}
this.innerText = "";
this.appendChild(div);
this.editor = new FocusEditorCore(div, text.trim() === "" ? "" : text);
if (this.hasAttribute("autofocus")) {
this.editor.focus = true;
}
this.editor.tabSize = this.getAttribute("tab-size");
if (this.hasAttribute("placeholder")) {
this.editor.placeholder = this.getAttribute("placeholder");
}
this.addEventListener("input", () =>
this.#syncValueForTextareaElementDebounced(),
);
this.addEventListener("keydown", () =>
this.#syncValueForTextareaElementDebounced(),
);
this.addEventListener("keyup", () =>
this.#syncValueForTextareaElementDebounced(),
);
}
#syncValueForTextareaElement = (inputName = this.getAttribute("name")) => {
if (!inputName) {
return;
}
let textArea = this.querySelector(`textarea[name="${inputName}"]`);
if (!textArea) {
textArea = document.createElement("textarea");
textArea.name = inputName;
textArea.style.display = "none";
this.appendChild(textArea);
}
textArea.innerText = this.value;
};
#syncValueForTextareaElementDebounced = debounce(
this.#syncValueForTextareaElement,
10,
);
set value(text) {
this.editor.replaceText(text, { clearHistory: true });
}
get value() {
return this.editor.getMarkdown();
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === "tab-size") {
this.editor.tabSize = newValue;
}
if (name === "readonly") {
this.editor.readonly = newValue != "true";
}
if (name === "placeholder") {
this.editor.placeholder = newValue;
}
if (name === "name") {
this.#syncValueForTextareaElement(newValue);
}
}
}
export default FocusEditorWebComponent;
source