Install and use ToastUi markdown editor
Replace all usages of pagedown-bootstrap editor with the new editor. Add styles to ensure the editor preview matches the final output.
This commit is contained in:

committed by
Dominic Sauer

parent
96f5f1f8d7
commit
9c71c6667a
77
app/assets/javascripts/markdown_editor.js
Normal file
77
app/assets/javascripts/markdown_editor.js
Normal file
@ -0,0 +1,77 @@
|
||||
/**
|
||||
* ToastUi editor initializer
|
||||
*
|
||||
* This script transforms form textareas created with
|
||||
* "PagedownFormBuilder" into ToastUi markdown editors.
|
||||
*
|
||||
*/
|
||||
|
||||
const initializeMarkdownEditors = () => {
|
||||
const editors = document.querySelectorAll(
|
||||
'[data-behavior="markdown-editor-widget"]'
|
||||
);
|
||||
|
||||
editors.forEach((editor) => {
|
||||
const formInput = document.querySelector(`#${editor.dataset.id}`);
|
||||
if (!editor || !formInput) return;
|
||||
|
||||
const toastEditor = new ToastUi({
|
||||
el: editor,
|
||||
theme: window.getCurrentTheme(),
|
||||
initialValue: formInput.value,
|
||||
placeholder: formInput.placeholder,
|
||||
extendedAutolinks: true,
|
||||
linkAttributes: {
|
||||
target: "_blank",
|
||||
},
|
||||
previewHighlight: false,
|
||||
height: "400px",
|
||||
autofocus: false,
|
||||
usageStatistics: false,
|
||||
language: I18n.locale,
|
||||
toolbarItems: [
|
||||
["heading", "bold", "italic"],
|
||||
["link", "quote", "code", "codeblock"],
|
||||
["ul", "ol"],
|
||||
],
|
||||
initialEditType: "markdown",
|
||||
events: {
|
||||
change: () => {
|
||||
// Keep real form <textarea> in sync
|
||||
const content = toastEditor.getMarkdown();
|
||||
formInput.value = content;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Prevent user from drag'n'dropping images in the editor
|
||||
toastEditor.removeHook("addImageBlobHook");
|
||||
|
||||
// Delegate focus from form input to toast ui editor
|
||||
formInput.addEventListener("focus", () => {
|
||||
toastEditor.focus();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const setMarkdownEditorTheme = (theme) => {
|
||||
const editors = document.querySelectorAll(".toastui-editor-defaultUI");
|
||||
editors.forEach((editor) => {
|
||||
const hasDarkTheme = editor.classList.contains("toastui-editor-dark");
|
||||
if (
|
||||
(hasDarkTheme && theme === "light") ||
|
||||
(!hasDarkTheme && theme === "dark")
|
||||
) {
|
||||
editor.classList.toggle("toastui-editor-dark");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$(document).on("turbolinks:load", function () {
|
||||
initializeMarkdownEditors();
|
||||
});
|
||||
|
||||
$(document).on("theme:change", function (event) {
|
||||
const newTheme = event.detail.currentTheme;
|
||||
setMarkdownEditorTheme(newTheme);
|
||||
});
|
@ -3,7 +3,12 @@ h1 {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@ -12,26 +17,36 @@ h1, h2, h3, h4, h5, h6 {
|
||||
color: var(--bs-dark-text-emphasis);
|
||||
}
|
||||
|
||||
a:not(.dropdown-item, .dropdown-toggle, .dropdown-link, .btn, .page-link), .btn-link {
|
||||
a:not(.dropdown-item, .dropdown-toggle, .dropdown-link, .btn, .page-link),
|
||||
.btn-link {
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
i.fa-solid, i.fa-regular, i.fa-solid {
|
||||
i.fa-solid,
|
||||
i.fa-regular,
|
||||
i.fa-solid {
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
pre, .output-element {
|
||||
pre,
|
||||
.output-element {
|
||||
background-color: var(--bs-light-bg-subtle);
|
||||
margin: 0;
|
||||
padding: .25rem!important;
|
||||
padding: 0.25rem !important;
|
||||
border: 1px solid var(--bs-border-color-translucent);
|
||||
}
|
||||
|
||||
blockquote {
|
||||
border-left: 4px solid var(--bs-secondary-bg);
|
||||
color: var(--bs-secondary-text-emphasis);
|
||||
margin: 14px 0;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
span.caret {
|
||||
margin-left: 0.5em;
|
||||
}
|
||||
@ -125,19 +140,25 @@ html[data-bs-theme="light"] {
|
||||
}
|
||||
|
||||
@-webkit-keyframes sk-rotateplane {
|
||||
0% { -webkit-transform: perspective(120px) }
|
||||
50% { -webkit-transform: perspective(120px) rotateY(180deg) }
|
||||
100% { -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg) }
|
||||
0% {
|
||||
-webkit-transform: perspective(120px);
|
||||
}
|
||||
50% {
|
||||
-webkit-transform: perspective(120px) rotateY(180deg);
|
||||
}
|
||||
100% {
|
||||
-webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes sk-rotateplane {
|
||||
0% {
|
||||
transform: perspective(120px) rotateX(0deg) rotateY(0deg);
|
||||
-webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg)
|
||||
-webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg);
|
||||
}
|
||||
50% {
|
||||
transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
|
||||
-webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg)
|
||||
-webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
|
||||
|
Reference in New Issue
Block a user