diff --git a/app/assets/javascripts/markdown_editor.js b/app/assets/javascripts/markdown_editor.js index e44f93f0..d8950ae6 100644 --- a/app/assets/javascripts/markdown_editor.js +++ b/app/assets/javascripts/markdown_editor.js @@ -1,7 +1,7 @@ /** * ToastUi editor initializer * - * This script transforms form textareas created with + * This script transforms form textareas created with * "MarkdownFormBuilder" into ToastUi markdown editors. * */ @@ -25,7 +25,7 @@ const initializeMarkdownEditors = () => { target: "_blank", }, previewHighlight: false, - height: "400px", + height: "300px", autofocus: false, usageStatistics: false, language: I18n.locale, @@ -45,6 +45,8 @@ const initializeMarkdownEditors = () => { }, }); + setResizeBtn(formInput, toastEditor); + // Prevent user from drag'n'dropping images in the editor toastEditor.removeHook("addImageBlobHook"); @@ -82,6 +84,48 @@ const setMarkdownEditorTheme = (theme) => { }); }; +const hasScrollBar = (el) => el.scrollHeight > el.clientHeight; +const toggleScrollbarModifier = (btn, el) => { + if (el.clientHeight === 0) return; + btn.classList.toggle( + "markdown-editor__resize-btn--with-scrollbar", + hasScrollBar(el) + ); +}; +const setResizeBtn = (formInput, editor) => { + const resizeBtn = document.querySelector(`#${formInput.id}-resize`); + if (!resizeBtn) return; + + const editorTextArea = editor + .getEditorElements() + .mdEditor.querySelector('[contenteditable="true"]'); + + toggleScrollbarModifier(resizeBtn, editorTextArea); + new MutationObserver(() => { + toggleScrollbarModifier(resizeBtn, editorTextArea); + }).observe(editorTextArea, { + attributes: true, + }); + + resizeBtn.addEventListener("click", () => { + const height = editor.getHeight(); + + if (height && height === "300px") { + editor.setHeight("auto"); + editor.setMinHeight("400px"); + resizeBtn.classList.add("markdown-editor__resize-btn--collapse"); + resizeBtn.title = I18n.t("markdown_editor.collapse"); + resizeBtn.ariaLabel = I18n.t("markdown_editor.collapse"); + } else { + editor.setHeight("300px"); + editor.setMinHeight("300px"); + resizeBtn.classList.remove("markdown-editor__resize-btn--collapse"); + resizeBtn.title = I18n.t("markdown_editor.expand"); + resizeBtn.ariaLabel = I18n.t("markdown_editor.expand"); + } + }); +}; + $(document).on("turbolinks:load", function () { initializeMarkdownEditors(); disableImageUpload(); diff --git a/app/helpers/markdown_form_builder.rb b/app/helpers/markdown_form_builder.rb index ca067ee0..b24bf30b 100644 --- a/app/helpers/markdown_form_builder.rb +++ b/app/helpers/markdown_form_builder.rb @@ -8,7 +8,7 @@ class MarkdownFormBuilder < ActionView::Helpers::FormBuilder @template.capture do @template.concat form_textarea - @template.concat @template.tag.div(class: 'markdown-editor', data: {behavior: 'markdown-editor-widget', id: label_target}) + @template.concat toast_ui_editor end end @@ -21,6 +21,18 @@ class MarkdownFormBuilder < ActionView::Helpers::FormBuilder class: 'd-none' end + def toast_ui_editor + @template.tag.div(class: 'markdown-editor__wrapper') do + @template.concat @template.tag.div(class: 'markdown-editor', data: {behavior: 'markdown-editor-widget', id: label_target}) + @template.concat resize_btn + end + end + + def resize_btn + @template.tag.button(class: 'markdown-editor__resize-btn fa-solid', type: 'button', id: "#{label_target}-resize", + title: I18n.t(:'markdown_editor.expand'), aria_label: I18n.t(:'markdown_editor.expand')) + end + def base_id options[:markdown_id_suffix] || @attribute_name end diff --git a/app/javascript/toast-ui.scss b/app/javascript/toast-ui.scss index 101a2093..cb43a999 100644 --- a/app/javascript/toast-ui.scss +++ b/app/javascript/toast-ui.scss @@ -5,6 +5,36 @@ * { box-sizing: content-box; } + + &__wrapper { + position: relative; + } + + &__resize-btn { + box-sizing: border-box; + position: absolute; + bottom: 30px; + right: 0; + background: transparent; + border: 1px solid transparent; + color: var(--bs-secondary-text-emphasis); + z-index: 100; + &::after { + content: "\f065"; + } + &--with-scrollbar { + right: 18px; + } + &--collapse { + right: 0; + &::after { + content: "\f066"; + } + } + &:hover { + background: var(--bs-secondary-bg); + } + } } // /*------------------------------------*\ diff --git a/config/locales/de.yml b/config/locales/de.yml index f5f1fac6..9b28e681 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -835,6 +835,9 @@ de:
This mail was automatically sent by CodeOcean.
subject: "Eine Aufgabe auf CodeOcean benötigt Ihr Feedback" + markdown_editor: + expand: Editor aufklappen + collapse: Editor zuklappen request_for_comments: click_here: Zum Kommentieren auf die Seitenleiste klicken! comments: Kommentare diff --git a/config/locales/en.yml b/config/locales/en.yml index fd902ca6..288b83f9 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -835,6 +835,9 @@ en:
This mail was automatically sent by CodeOcean.
subject: "An exercise on CodeOcean needs your feedback" + markdown_editor: + expand: Expand editor + collapse: Collapse editor request_for_comments: click_here: Click on this sidebar to comment! comments: Comments