From 749074fec03cefa8fe920b42be8c26bb1147ed02 Mon Sep 17 00:00:00 2001
From: Julia Casamitjana <62883011+JuliaCasamitjana@users.noreply.github.com>
Date: Mon, 15 Apr 2024 13:23:00 +0200
Subject: [PATCH] Add functionality to expand the markdown editor
The editor will now have a default height of 300px but a button will let
the user expand the editor. It will expand it to fit all content (or up
to 400px if the content was not exceeding 300px). In the expanded mode
the editor will keep growing as the user types more content.
---
app/assets/javascripts/markdown_editor.js | 48 ++++++++++++++++++++++-
app/helpers/markdown_form_builder.rb | 14 ++++++-
app/javascript/toast-ui.scss | 30 ++++++++++++++
config/locales/de.yml | 3 ++
config/locales/en.yml | 3 ++
5 files changed, 95 insertions(+), 3 deletions(-)
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