67 lines
2.2 KiB
JavaScript
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;
|
|
}
|
|
}
|