Some improvments for the text editor
parent
4a6478c78b
commit
3c486f7610
|
|
@ -101,11 +101,11 @@ public class MvcArticleTextBodyStep extends AbstractMvcAuthoringStep {
|
|||
private ItemPermissionChecker itemPermissionChecker;
|
||||
|
||||
private Map<String, String> textValues;
|
||||
|
||||
|
||||
private List<CmsEditorLocaleVariantRow> variants;
|
||||
|
||||
private List<String> unusedLocales;
|
||||
|
||||
|
||||
private String selectedLocale;
|
||||
|
||||
@Override
|
||||
|
|
@ -150,7 +150,7 @@ public class MvcArticleTextBodyStep extends AbstractMvcAuthoringStep {
|
|||
public Map<String, String> getTextValues() {
|
||||
return Collections.unmodifiableMap(textValues);
|
||||
}
|
||||
|
||||
|
||||
public List<CmsEditorLocaleVariantRow> getVariants() {
|
||||
return Collections.unmodifiableList(variants);
|
||||
}
|
||||
|
|
@ -167,7 +167,7 @@ public class MvcArticleTextBodyStep extends AbstractMvcAuthoringStep {
|
|||
public String getSelectedLocale() {
|
||||
return selectedLocale;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a localized main text.
|
||||
*
|
||||
|
|
@ -203,9 +203,11 @@ public class MvcArticleTextBodyStep extends AbstractMvcAuthoringStep {
|
|||
if (itemPermissionChecker.canEditItem(getArticle())) {
|
||||
final String value;
|
||||
if (getArticle().getText().getAvailableLocales().isEmpty()) {
|
||||
value = "Lorem ipsum";
|
||||
value = "";
|
||||
} else {
|
||||
value = getArticle().getText().getValue(defaultLocale);
|
||||
value = globalizationHelper.getValueFromLocalizedString(
|
||||
getArticle().getText()
|
||||
);
|
||||
}
|
||||
final Locale locale = new Locale(localeParam);
|
||||
getArticle().getText().addValue(locale, value);
|
||||
|
|
@ -220,7 +222,7 @@ public class MvcArticleTextBodyStep extends AbstractMvcAuthoringStep {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// @GET
|
||||
//// @Path("/{locale}/@view")
|
||||
// @Path("/variants/{locale}")
|
||||
|
|
@ -253,8 +255,6 @@ public class MvcArticleTextBodyStep extends AbstractMvcAuthoringStep {
|
|||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
@GET
|
||||
@Path("/edit/{locale}")
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
|
|
@ -265,7 +265,7 @@ public class MvcArticleTextBodyStep extends AbstractMvcAuthoringStep {
|
|||
final String documentPath,
|
||||
@PathParam("locale") final String localeParam
|
||||
) {
|
||||
try {
|
||||
try {
|
||||
init();
|
||||
} catch (ContentSectionNotFoundException ex) {
|
||||
return ex.showErrorMessage();
|
||||
|
|
@ -275,7 +275,7 @@ public class MvcArticleTextBodyStep extends AbstractMvcAuthoringStep {
|
|||
|
||||
if (itemPermissionChecker.canEditItem(getArticle())) {
|
||||
selectedLocale = new Locale(localeParam).toString();
|
||||
|
||||
|
||||
return "org/librecms/ui/contenttypes/article/article-text/edit.xhtml";
|
||||
} else {
|
||||
return documentUi.showAccessDenied(
|
||||
|
|
@ -390,7 +390,7 @@ public class MvcArticleTextBodyStep extends AbstractMvcAuthoringStep {
|
|||
entry -> entry.getValue()
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
variants = getArticle()
|
||||
.getText()
|
||||
.getValues()
|
||||
|
|
@ -414,17 +414,18 @@ public class MvcArticleTextBodyStep extends AbstractMvcAuthoringStep {
|
|||
private Article getArticle() {
|
||||
return (Article) getDocument();
|
||||
}
|
||||
|
||||
|
||||
private CmsEditorLocaleVariantRow buildVariantRow(
|
||||
final Map.Entry<Locale, String> entry
|
||||
) {
|
||||
final CmsEditorLocaleVariantRow variant = new CmsEditorLocaleVariantRow();
|
||||
final CmsEditorLocaleVariantRow variant
|
||||
= new CmsEditorLocaleVariantRow();
|
||||
variant.setLocale(entry.getKey().toString());
|
||||
final Document document = Jsoup.parseBodyFragment(entry.getValue());
|
||||
variant.setWordCount(
|
||||
new StringTokenizer(document.body().text()).countTokens()
|
||||
);
|
||||
|
||||
|
||||
return variant;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -63,10 +63,10 @@ public class MvcArticleTextBodyStepResources {
|
|||
private ItemPermissionChecker itemPermissionChecker;
|
||||
|
||||
@GET
|
||||
@Path("/variants/{locale}/wordcount")
|
||||
@Path("/variants/wordcount/{locale}")
|
||||
@Produces(MediaType.TEXT_HTML)
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public long getWordCount(
|
||||
public String getWordCount(
|
||||
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||
final String sectionIdentifier,
|
||||
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
|
||||
|
|
@ -95,7 +95,8 @@ public class MvcArticleTextBodyStepResources {
|
|||
.getText()
|
||||
.getValue(new Locale(localeParam));
|
||||
final Document jsoupDoc = Jsoup.parseBodyFragment(text);
|
||||
return new StringTokenizer(jsoupDoc.body().text()).countTokens();
|
||||
long result = new StringTokenizer(jsoupDoc.body().text()).countTokens();
|
||||
return Long.toString(result);
|
||||
} else {
|
||||
throw new ForbiddenException();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -183,6 +183,10 @@
|
|||
<cc:attribute name="viewDialogCloseButtonLabel"
|
||||
default="Close"
|
||||
type="String" />
|
||||
<cc:attribute name="wordCountUrl"
|
||||
required="true"
|
||||
shortDescription="URL of the endpoint for retrieving the wordcount of a variant. The locale of the variant to retrieve is appended as last token."
|
||||
type="String" />
|
||||
</cc:interface>
|
||||
<cc:implementation>
|
||||
<div class="cms-editor"
|
||||
|
|
@ -358,6 +362,7 @@
|
|||
data-locale="#{variant.locale}"
|
||||
data-variant-url="#{cc.attrs.variantUrl}/#{variant.locale}"
|
||||
data-save-url="#{cc.attrs.editMethod}/#{variant.locale}"
|
||||
data-wordcount-url="#{cc.attrs.wordCountUrl}/#{variant.locale}"
|
||||
type="button">
|
||||
<bootstrap:svgIcon icon="pen" />
|
||||
<span class="sr-only">
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
unusedLocales="#{CmsArticleTextBodyStep.unusedLocales}"
|
||||
variantUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@article-text-resources/variants"
|
||||
variants="#{CmsArticleTextBodyStep.variants}"
|
||||
wordCountUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@article-text-resources/variants/wordcount"
|
||||
/>
|
||||
|
||||
</ui:define>
|
||||
|
|
|
|||
|
|
@ -3,211 +3,223 @@ import * as $ from "jquery";
|
|||
import { Editor } from "@tiptap/core";
|
||||
import StarterKit from "@tiptap/starter-kit";
|
||||
|
||||
function showMessage(messageId: string) {
|
||||
const template = document.querySelector(messageId) as HTMLTemplateElement;
|
||||
const msg = template.content.cloneNode(true);
|
||||
document.querySelector(".cms-editor-messages").append(msg);
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function (event) {
|
||||
document
|
||||
.querySelector(
|
||||
".cms-editor .cms-editor-variants .cms-editor-view-button"
|
||||
)
|
||||
.addEventListener("click", function (event) {
|
||||
event.preventDefault();
|
||||
const viewButtons = document.querySelectorAll(
|
||||
".cms-editor .cms-editor-variants .cms-editor-view-button"
|
||||
);
|
||||
for (let i = 0; i < viewButtons.length; i++) {
|
||||
viewButtons[i].addEventListener("click", event =>
|
||||
showViewDialog(event)
|
||||
);
|
||||
}
|
||||
|
||||
const target = event.currentTarget as Element;
|
||||
const variantUrl = target.getAttribute("data-variant-url");
|
||||
const viewDialogId = target.getAttribute("data-view-dialog");
|
||||
const editButtons = document.querySelectorAll(
|
||||
".cms-editor .cms-editor-variants .cms-editor-edit-button"
|
||||
);
|
||||
for (let i = 0; i < editButtons.length; i++) {
|
||||
editButtons[i].addEventListener("click", event =>
|
||||
showEditDialog(event)
|
||||
);
|
||||
}
|
||||
|
||||
fetch(variantUrl, {
|
||||
method: "GET",
|
||||
credentials: "include"
|
||||
})
|
||||
.then(response => {
|
||||
if (response.ok) {
|
||||
response
|
||||
.text()
|
||||
.then(text => {
|
||||
const viewDialog = document.querySelector(
|
||||
`#${viewDialogId}`
|
||||
);
|
||||
const viewDialogBody = viewDialog.querySelector(
|
||||
".modal-body"
|
||||
);
|
||||
// document
|
||||
// .querySelector(
|
||||
// ".cms-editor .cms-editor-variants .cms-editor-view-button"
|
||||
// )
|
||||
// .addEventListener("click", function (event) {
|
||||
// event.preventDefault();
|
||||
|
||||
viewDialogBody.textContent = text;
|
||||
// const target = event.currentTarget as Element;
|
||||
// const variantUrl = target.getAttribute("data-variant-url");
|
||||
// const viewDialogId = target.getAttribute("data-view-dialog");
|
||||
|
||||
$(`#${viewDialogId}`).modal("toggle");
|
||||
})
|
||||
.catch(err => {
|
||||
showMessage(
|
||||
"#cms-editor-msg-variant-load-failed"
|
||||
);
|
||||
});
|
||||
} else {
|
||||
showMessage("#cms-editor-msg-variant-load-failed");
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
showMessage("#cms-editor-msg-variant-load-failed");
|
||||
});
|
||||
});
|
||||
// fetch(variantUrl, {
|
||||
// method: "GET",
|
||||
// credentials: "include"
|
||||
// })
|
||||
// .then(response => {
|
||||
// if (response.ok) {
|
||||
// response
|
||||
// .text()
|
||||
// .then(text => {
|
||||
// const viewDialog = document.querySelector(
|
||||
// `#${viewDialogId}`
|
||||
// );
|
||||
// const viewDialogBody =
|
||||
// viewDialog.querySelector(".modal-body");
|
||||
|
||||
document
|
||||
.querySelector(
|
||||
".cms-editor .cms-editor-variants .cms-editor-edit-button"
|
||||
)
|
||||
.addEventListener("click", function (event) {
|
||||
event.preventDefault();
|
||||
// viewDialogBody.textContent = text;
|
||||
|
||||
const target = event.currentTarget as Element;
|
||||
const locale = target.getAttribute("data-locale");
|
||||
const variantUrl = target.getAttribute("data-variant-url");
|
||||
const editDialogId = target.getAttribute("data-edit-dialog");
|
||||
const saveUrl = target.getAttribute("data-save-url");
|
||||
// $(`#${viewDialogId}`).modal("toggle");
|
||||
// })
|
||||
// .catch(err => {
|
||||
// showMessage(
|
||||
// "#cms-editor-msg-variant-load-failed"
|
||||
// );
|
||||
// });
|
||||
// } else {
|
||||
// showMessage("#cms-editor-msg-variant-load-failed");
|
||||
// }
|
||||
// })
|
||||
// .catch(err => {
|
||||
// showMessage("#cms-editor-msg-variant-load-failed");
|
||||
// });
|
||||
// });
|
||||
|
||||
fetch(variantUrl, {
|
||||
method: "GET",
|
||||
credentials: "include"
|
||||
})
|
||||
.then(response => {
|
||||
if (response.ok) {
|
||||
response
|
||||
.text()
|
||||
.then(text => {
|
||||
const editDialog = document.querySelector(
|
||||
`#${editDialogId}`
|
||||
);
|
||||
const tiptapDiv = editDialog.querySelector(
|
||||
".modal-body .cms-tiptap-editor"
|
||||
);
|
||||
if (!tiptapDiv) {
|
||||
console.warn("tiptapDiv is null");
|
||||
}
|
||||
// document
|
||||
// .querySelector(
|
||||
// ".cms-editor .cms-editor-variants .cms-editor-edit-button"
|
||||
// )
|
||||
// .addEventListener("click", function (event) {
|
||||
// event.preventDefault();
|
||||
|
||||
const editor = new Editor({
|
||||
element: tiptapDiv,
|
||||
extensions: [StarterKit],
|
||||
content: text
|
||||
});
|
||||
// const target = event.currentTarget as Element;
|
||||
// const locale = target.getAttribute("data-locale");
|
||||
// const variantUrl = target.getAttribute("data-variant-url");
|
||||
// const editDialogId = target.getAttribute("data-edit-dialog");
|
||||
// const saveUrl = target.getAttribute("data-save-url");
|
||||
|
||||
const buttonsDiv = editDialog.querySelector(
|
||||
".cms-tiptap-editor-buttons"
|
||||
);
|
||||
if (!buttonsDiv) {
|
||||
console.warn("buttonsDiv is null.");
|
||||
}
|
||||
const emphButton = buttonsDiv.querySelector(
|
||||
".tiptap-emph"
|
||||
);
|
||||
if (!emphButton) {
|
||||
console.warn("emphButton not found.");
|
||||
}
|
||||
emphButton.addEventListener("click", event => {
|
||||
event.preventDefault();
|
||||
editor.chain().focus().toggleItalic().run();
|
||||
});
|
||||
// fetch(variantUrl, {
|
||||
// method: "GET",
|
||||
// credentials: "include"
|
||||
// })
|
||||
// .then(response => {
|
||||
// if (response.ok) {
|
||||
// response
|
||||
// .text()
|
||||
// .then(text => {
|
||||
// const editDialog = document.querySelector(
|
||||
// `#${editDialogId}`
|
||||
// );
|
||||
// const tiptapDiv = editDialog.querySelector(
|
||||
// ".modal-body .cms-tiptap-editor"
|
||||
// );
|
||||
// if (!tiptapDiv) {
|
||||
// console.warn("tiptapDiv is null");
|
||||
// }
|
||||
|
||||
const strongEmphButton = buttonsDiv.querySelector(
|
||||
".tiptap-strong-emph"
|
||||
);
|
||||
if (!strongEmphButton) {
|
||||
console.warn("strongEmphButton not found.");
|
||||
}
|
||||
strongEmphButton.addEventListener(
|
||||
"click",
|
||||
event => {
|
||||
event.preventDefault();
|
||||
editor
|
||||
.chain()
|
||||
.focus()
|
||||
.toggleBold()
|
||||
.run();
|
||||
}
|
||||
);
|
||||
// const editor = new Editor({
|
||||
// element: tiptapDiv,
|
||||
// extensions: [StarterKit],
|
||||
// content: text
|
||||
// });
|
||||
|
||||
const closeButton = editDialog.querySelector(
|
||||
".modal-header .close"
|
||||
);
|
||||
const cancelButton = editDialog.querySelector(
|
||||
".modal-footer .cms-editor-cancel-button"
|
||||
);
|
||||
const saveButton = editDialog.querySelector(
|
||||
".modal-footer .cms-editor-save-button"
|
||||
);
|
||||
// const buttonsDiv = editDialog.querySelector(
|
||||
// ".cms-tiptap-editor-buttons"
|
||||
// );
|
||||
// if (!buttonsDiv) {
|
||||
// console.warn("buttonsDiv is null.");
|
||||
// }
|
||||
// const emphButton =
|
||||
// buttonsDiv.querySelector(".tiptap-emph");
|
||||
// if (!emphButton) {
|
||||
// console.warn("emphButton not found.");
|
||||
// }
|
||||
// emphButton.addEventListener("click", event => {
|
||||
// event.preventDefault();
|
||||
// editor.chain().focus().toggleItalic().run();
|
||||
// });
|
||||
|
||||
closeButton.addEventListener("click", event => {
|
||||
editor.chain().clearContent();
|
||||
editor.destroy();
|
||||
$(`#${editDialogId}`).modal("toggle");
|
||||
});
|
||||
// const strongEmphButton =
|
||||
// buttonsDiv.querySelector(
|
||||
// ".tiptap-strong-emph"
|
||||
// );
|
||||
// if (!strongEmphButton) {
|
||||
// console.warn("strongEmphButton not found.");
|
||||
// }
|
||||
// strongEmphButton.addEventListener(
|
||||
// "click",
|
||||
// event => {
|
||||
// event.preventDefault();
|
||||
// editor
|
||||
// .chain()
|
||||
// .focus()
|
||||
// .toggleBold()
|
||||
// .run();
|
||||
// }
|
||||
// );
|
||||
|
||||
cancelButton.addEventListener(
|
||||
"click",
|
||||
event => {
|
||||
editor.chain().clearContent();
|
||||
editor.destroy();
|
||||
$(`#${editDialogId}`).modal("toggle");
|
||||
}
|
||||
);
|
||||
// const closeButton = editDialog.querySelector(
|
||||
// ".modal-header .close"
|
||||
// );
|
||||
// const cancelButton = editDialog.querySelector(
|
||||
// ".modal-footer .cms-editor-cancel-button"
|
||||
// );
|
||||
// const saveButton = editDialog.querySelector(
|
||||
// ".modal-footer .cms-editor-save-button"
|
||||
// );
|
||||
|
||||
saveButton.addEventListener("click", event => {
|
||||
const html = editor.getHTML();
|
||||
const params = new URLSearchParams();
|
||||
params.append("value", html);
|
||||
fetch(saveUrl, {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded"
|
||||
},
|
||||
body: params
|
||||
})
|
||||
.then(saveResponse => {
|
||||
if (saveResponse.ok) {
|
||||
showMessage(
|
||||
"#cms-editor-msg-save-successful"
|
||||
);
|
||||
window.location.reload();
|
||||
} else {
|
||||
showMessage(
|
||||
"#cms-editor-msg-save-failed"
|
||||
);
|
||||
}
|
||||
$(`#${editDialogId}`).modal(
|
||||
"toggle"
|
||||
);
|
||||
})
|
||||
.catch(err => {
|
||||
showMessage(
|
||||
"#cms-editor-msg-save-failed"
|
||||
);
|
||||
console.error(err);
|
||||
$(`#${editDialogId}`).modal(
|
||||
"toggle"
|
||||
);
|
||||
});
|
||||
});
|
||||
// closeButton.addEventListener("click", event => {
|
||||
// editor.chain().clearContent();
|
||||
// editor.destroy();
|
||||
// $(`#${editDialogId}`).modal("toggle");
|
||||
// });
|
||||
|
||||
$(`#${editDialogId}`).modal("toggle");
|
||||
})
|
||||
.catch(err => {
|
||||
showMessage(
|
||||
"#cms-editor-msg-variant-load-failed"
|
||||
);
|
||||
console.error(err);
|
||||
});
|
||||
} else {
|
||||
showMessage("#cms-editor-msg-variant-load-failed");
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
showMessage("#cms-editor-msg-variant-load-failed");
|
||||
console.error(err);
|
||||
});
|
||||
});
|
||||
// cancelButton.addEventListener(
|
||||
// "click",
|
||||
// event => {
|
||||
// editor.chain().clearContent();
|
||||
// editor.destroy();
|
||||
// $(`#${editDialogId}`).modal("toggle");
|
||||
// }
|
||||
// );
|
||||
|
||||
// saveButton.addEventListener("click", event => {
|
||||
// const html = editor.getHTML();
|
||||
// const params = new URLSearchParams();
|
||||
// params.append("value", html);
|
||||
// fetch(saveUrl, {
|
||||
// method: "POST",
|
||||
// credentials: "include",
|
||||
// headers: {
|
||||
// "Content-Type":
|
||||
// "application/x-www-form-urlencoded"
|
||||
// },
|
||||
// body: params
|
||||
// })
|
||||
// .then(saveResponse => {
|
||||
// if (saveResponse.ok) {
|
||||
// showMessage(
|
||||
// "#cms-editor-msg-save-successful"
|
||||
// );
|
||||
// window.location.reload();
|
||||
// } else {
|
||||
// showMessage(
|
||||
// "#cms-editor-msg-save-failed"
|
||||
// );
|
||||
// }
|
||||
// $(`#${editDialogId}`).modal(
|
||||
// "toggle"
|
||||
// );
|
||||
// })
|
||||
// .catch(err => {
|
||||
// showMessage(
|
||||
// "#cms-editor-msg-save-failed"
|
||||
// );
|
||||
// console.error(err);
|
||||
// $(`#${editDialogId}`).modal(
|
||||
// "toggle"
|
||||
// );
|
||||
// });
|
||||
// });
|
||||
|
||||
// $(`#${editDialogId}`).modal("toggle");
|
||||
// })
|
||||
// .catch(err => {
|
||||
// showMessage(
|
||||
// "#cms-editor-msg-variant-load-failed"
|
||||
// );
|
||||
// console.error(err);
|
||||
// });
|
||||
// } else {
|
||||
// showMessage("#cms-editor-msg-variant-load-failed");
|
||||
// }
|
||||
// })
|
||||
// .catch(err => {
|
||||
// showMessage("#cms-editor-msg-variant-load-failed");
|
||||
// console.error(err);
|
||||
// });
|
||||
// });
|
||||
|
||||
// console.log("Starting editor");
|
||||
// new Editor({
|
||||
|
|
@ -218,3 +230,209 @@ document.addEventListener("DOMContentLoaded", function (event) {
|
|||
// content: '<h1>Hello World</h1>'
|
||||
// })
|
||||
});
|
||||
|
||||
function closeEditor(event: Event, editor: Editor, editDialogId: string) {
|
||||
event.preventDefault();
|
||||
|
||||
editor.chain().clearContent();
|
||||
editor.destroy();
|
||||
$(`#${editDialogId}`).modal("toggle");
|
||||
}
|
||||
|
||||
async function fetchVariant(fromUrl: string) {
|
||||
try {
|
||||
const response = await fetch(fromUrl, {
|
||||
method: "GET",
|
||||
credentials: "include"
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
return await response.text();
|
||||
} else {
|
||||
showLoadVariantFailedMessage(response.status, response.statusText);
|
||||
}
|
||||
} catch (err) {
|
||||
showLoadVariantFailedErrMessage(err);
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchWordCount(fromUrl: string) {
|
||||
try {
|
||||
const response = await fetch(fromUrl, {
|
||||
method: "GET",
|
||||
credentials: "include"
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
return await response.text();
|
||||
} else {
|
||||
return "?";
|
||||
}
|
||||
} catch (err) {
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
|
||||
function initEditorButtons(editor: Editor, buttonsElem: Element) {
|
||||
// const emphButton: HTMLButtonElement | null = buttonsElem.querySelector(
|
||||
// ".tiptap-emph"
|
||||
// );
|
||||
// if(emphButton) {
|
||||
// emphButton.addEventListener("click", event => {
|
||||
// event.preventDefault();
|
||||
// editor.chain().focus().toggleItalic().run();
|
||||
// });
|
||||
// }
|
||||
buttonsElem
|
||||
.querySelector(".tiptap-emph")
|
||||
?.addEventListener("click", event => {
|
||||
event.preventDefault();
|
||||
editor.chain().focus().toggleItalic().run();
|
||||
});
|
||||
|
||||
buttonsElem
|
||||
.querySelector(".tiptap-strong-emph")
|
||||
?.addEventListener("click", event => {
|
||||
event.preventDefault();
|
||||
editor.chain().focus().toggleBold().run();
|
||||
});
|
||||
}
|
||||
|
||||
async function showEditDialog(event: Event) {
|
||||
event.preventDefault();
|
||||
|
||||
const target = event.currentTarget as Element;
|
||||
const locale = target.getAttribute("data-locale");
|
||||
const variantUrl = target.getAttribute("data-variant-url");
|
||||
const editDialogId = target.getAttribute("data-edit-dialog");
|
||||
const saveUrl = target.getAttribute("data-save-url");
|
||||
const wordCountUrl = target.getAttribute("data-wordcount-url");
|
||||
|
||||
const variant = await fetchVariant(variantUrl);
|
||||
|
||||
const editDialog = document.querySelector(`#${editDialogId}`);
|
||||
const tiptapDiv = editDialog.querySelector(
|
||||
".modal-body .cms-tiptap-editor"
|
||||
);
|
||||
if (!tiptapDiv) {
|
||||
console.warn("tiptapDiv is null");
|
||||
return;
|
||||
}
|
||||
|
||||
const editor = new Editor({
|
||||
element: tiptapDiv,
|
||||
extensions: [StarterKit],
|
||||
content: variant
|
||||
});
|
||||
|
||||
initEditorButtons(
|
||||
editor,
|
||||
document.querySelector(".cms-tiptap-editor-buttons")
|
||||
);
|
||||
|
||||
editDialog
|
||||
.querySelector(".modal-header .close")
|
||||
.addEventListener("click", event =>
|
||||
closeEditor(event, editor, editDialogId)
|
||||
);
|
||||
editDialog
|
||||
.querySelector(".modal-footer .cms-editor-cancel-button")
|
||||
.addEventListener("click", event =>
|
||||
closeEditor(event, editor, editDialogId)
|
||||
);
|
||||
editDialog
|
||||
.querySelector(".modal-footer .cms-editor-save-button")
|
||||
.addEventListener("click", event =>
|
||||
save(event, editor, editDialogId, saveUrl, locale, wordCountUrl)
|
||||
);
|
||||
|
||||
$(`#${editDialogId}`).modal("toggle");
|
||||
}
|
||||
|
||||
async function save(
|
||||
event: Event,
|
||||
editor: Editor,
|
||||
editDialogId: string,
|
||||
saveUrl: string,
|
||||
locale: string,
|
||||
wordCountUrl: string
|
||||
) {
|
||||
event.preventDefault();
|
||||
|
||||
const params = new URLSearchParams();
|
||||
params.append("value", editor.getHTML());
|
||||
|
||||
try {
|
||||
const response = await fetch(saveUrl, {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
headers: {
|
||||
"Content-Type": "application/x-www-form-urlencoded"
|
||||
},
|
||||
body: params
|
||||
});
|
||||
if (response.ok) {
|
||||
showSaveSuccessfulMessage();
|
||||
} else {
|
||||
showSaveFailedMessage(response.status, response.statusText);
|
||||
}
|
||||
} catch (err) {
|
||||
showSaveFailedErrMessage(err);
|
||||
}
|
||||
|
||||
$(`#${editDialogId}`).modal("toggle");
|
||||
|
||||
const wordCount = await fetchWordCount(wordCountUrl);
|
||||
const wordCountSpan = document.querySelector(
|
||||
`tr#variant-${locale} .wordcount`
|
||||
);
|
||||
wordCountSpan.textContent = wordCount;
|
||||
}
|
||||
|
||||
function showLoadVariantFailedErrMessage(err) {
|
||||
showMessage("#cms-editor-msg-variant-load-failed");
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
function showLoadVariantFailedMessage(status: number, statusText: string) {
|
||||
showMessage("#cms-editor-msg-variant-load-failed");
|
||||
console.error(`HTTP Status: ${status}, statusText: ${statusText}`);
|
||||
}
|
||||
|
||||
function showMessage(messageId: string) {
|
||||
const template = document.querySelector(messageId) as HTMLTemplateElement;
|
||||
const msg = template.content.cloneNode(true);
|
||||
document.querySelector(".cms-editor-messages").append(msg);
|
||||
}
|
||||
|
||||
function showSaveFailedErrMessage(err) {
|
||||
showMessage("#cms-editor-msg-save-failed");
|
||||
console.error(err);
|
||||
}
|
||||
|
||||
function showSaveFailedMessage(status: number, statusText: string) {
|
||||
showMessage("#cms-editor-msg-save-failed");
|
||||
console.error(`HTTP Status: ${status}, statusText: ${statusText}`);
|
||||
}
|
||||
|
||||
function showSaveSuccessfulMessage() {
|
||||
showMessage("#cms-editor-msg-save-successful");
|
||||
}
|
||||
|
||||
async function showViewDialog(event: Event) {
|
||||
event.preventDefault();
|
||||
|
||||
const target = event.currentTarget as Element;
|
||||
const variantUrl = target.getAttribute("data-variant-url");
|
||||
const viewDialogId = target.getAttribute("data-view-dialog");
|
||||
|
||||
const variant = await fetchVariant(variantUrl);
|
||||
|
||||
const viewDialog = document.querySelector(`#${viewDialogId}`);
|
||||
|
||||
const viewDialogBody = viewDialog.querySelector(".modal-body");
|
||||
|
||||
viewDialogBody.innerHTML = variant;
|
||||
|
||||
$(`#${viewDialogId}`).modal("toggle");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue