Files
racket-wiki/static/js/wiki/cmap/dialogs/metadata-dialog.js
T

67 lines
2.2 KiB
JavaScript

/**
* Edit CMap metadata without knowing how the active CMap is persisted.
*
* The controller owns field population and validation. Its save handler
* receives normalized metadata and reports success with a boolean result.
*/
export class CmapMetadataDialog {
constructor(dialog, tr, normalizePageReference) {
this.dialog = dialog;
this.tr = tr;
this.normalizePageReference = normalizePageReference;
this.form = dialog.querySelector("form");
this.summary = dialog.querySelector("#cmap-metadata-summary");
this.tags = dialog.querySelector("#cmap-metadata-tags");
this.explanationPage = dialog.querySelector("#cmap-metadata-explanation-page");
this.saveHandler = null;
dialog.querySelector("#cmap-metadata-cancel")
.addEventListener("click", () => dialog.close());
this.explanationPage.addEventListener("input", () =>
this.explanationPage.setCustomValidity(""));
this.form.addEventListener("submit", (event) => {
event.preventDefault();
this.save().catch((error) => window.alert(error.message));
});
}
onSave(handler) {
this.saveHandler = handler;
return this;
}
open(metadata) {
this.summary.value = metadata.summary || "";
this.tags.value = (metadata.tags || []).join(", ");
this.explanationPage.value = metadata.explanationPageSlug || "";
this.explanationPage.setCustomValidity("");
this.dialog.showModal();
this.summary.focus();
}
metadata() {
const explanationInput = this.explanationPage.value.trim();
const explanationPageSlug = explanationInput ?
this.normalizePageReference(explanationInput) : "";
if (explanationInput && !explanationPageSlug) {
this.explanationPage.setCustomValidity(
this.tr("invalid-description-page", "Enter a valid description page address."));
this.explanationPage.reportValidity();
return null;
}
return {
tags: this.tags.value.split(",").map((tag) => tag.trim()).filter(Boolean),
summary: this.summary.value.trim(),
explanationPageSlug
};
}
async save() {
const metadata = this.metadata();
if (!metadata || !this.saveHandler) return false;
const saved = await this.saveHandler(metadata);
if (saved) this.dialog.close();
return saved;
}
}