("click", HTMLEditor.#stopPropagation);
// Avoid the hijack of the backspace key by the markup when the
// html editor is open.
this.#editorInner.addEventListener("keydown", HTMLEditor.#stopPropagation);
this.editor = new Editor(config);
this.editor.appendToLocalElement(this.#editorInner);
this.hide(false);
}
editor = null;
doc = null;
#container = null;
#editorInner = null;
#attachedElement = null;
#originalValue;
static #ctrl(k) {
return (Services.appinfo.OS == "Darwin" ? "Cmd-" : "Ctrl-") + k;
}
static #stopPropagation(e) {
e.stopPropagation();
}
/**
* Need to refresh position by manually setting CSS values, so this will
* need to be called on resizes and other sizing changes.
*/
refresh = () => {
const element = this.#attachedElement;
if (element) {
this.#container.style.top = element.offsetTop + "px";
this.#container.style.left = element.offsetLeft + "px";
this.#container.style.width = element.offsetWidth + "px";
this.#container.style.height = element.parentNode.offsetHeight + "px";
}
};
/**
* Anchor the editor to a particular element.
*
* @param {DOMNode} element
* The element that the editor will be anchored to.
* Should belong to the HTMLDocument passed into the constructor.
*/
#attach(element) {
this.#detach();
this.#attachedElement = element;
element.classList.add("html-editor-container");
this.refresh();
}
/**
* Unanchor the editor from an element.
*/
#detach() {
if (this.#attachedElement) {
this.#attachedElement.classList.remove("html-editor-container");
this.#attachedElement = undefined;
}
}
/**
* Anchor the editor to a particular element, and show the editor.
*
* @param {DOMNode} element
* The element that the editor will be anchored to.
* Should belong to the HTMLDocument passed into the constructor.
* @param {string} text
* Value to set the contents of the editor to
* @param {Function} cb
* The function to call when hiding
*/
show = (element, text) => {
if (this.isVisible) {
return;
}
this.#originalValue = text;
this.editor.setText(text, { saveTransactionToHistory: false });
this.#attach(element);
this.#container.style.display = "flex";
this.isVisible = true;
this.editor.focus();
this.emit("popupshown");
};
/**
* Hide the editor, optionally committing the changes
*
* @param {boolean} shouldCommit
* A change will be committed by default. If this param
* strictly equals false, no change will occur.
*/
hide = shouldCommit => {
if (!this.isVisible) {
return;
}
this.#container.style.display = "none";
this.#detach();
const newValue = this.editor.getText();
const valueHasChanged = this.#originalValue !== newValue;
const preventCommit = shouldCommit === false || !valueHasChanged;
this.#originalValue = undefined;
this.isVisible = undefined;
this.emit("popuphidden", !preventCommit, newValue);
};
/**
* Destroy this object and unbind all event handlers
*/
destroy() {
this.doc.defaultView.removeEventListener("resize", this.refresh, true);
this.#container.removeEventListener("click", this.hide);
this.#editorInner.removeEventListener("click", HTMLEditor.#stopPropagation);
this.#editorInner.removeEventListener(
"keydown",
HTMLEditor.#stopPropagation
);
this.hide(false);
this.#container.remove();
this.editor.destroy();
}
}
module.exports = HTMLEditor;
PK