From 66318698e5eddc6a56ce75e452ce1d70bdd8124e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lera=20Elvo=C3=A9?= Date: Sat, 24 May 2025 02:45:54 +0300 Subject: [PATCH] add reusable babycode editor --- data/static/style.css | 10 +++- js/post-editor.js | 54 ++++++++++++++++++++ js/thread.js | 14 ++--- sass/style.scss | 14 +++-- views/common/babycode-editor-component.etlua | 8 +++ views/common/babycode-editor.etlua | 16 ++++++ views/common/bbcode_help.etlua | 4 +- views/threads/create.etlua | 4 +- views/threads/post.etlua | 12 ++--- views/threads/thread.etlua | 13 ++--- 10 files changed, 116 insertions(+), 33 deletions(-) create mode 100644 js/post-editor.js create mode 100644 views/common/babycode-editor-component.etlua create mode 100644 views/common/babycode-editor.etlua diff --git a/data/static/style.css b/data/static/style.css index 63aae96..dd6994c 100644 --- a/data/static/style.css +++ b/data/static/style.css @@ -394,6 +394,12 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus align-items: baseline; height: 100%; } -.post-edit-form > textarea { - height: 100%; + +.babycode-editor { + height: 150px; +} + +ul { + margin: 10px 0 10px 30px; + padding: 0; } diff --git a/js/post-editor.js b/js/post-editor.js new file mode 100644 index 0000000..f7e344a --- /dev/null +++ b/js/post-editor.js @@ -0,0 +1,54 @@ +{ + let ta = document.getElementById("post_content"); + const buttonBold = document.getElementById("post-editor-bold"); + const buttonItalics = document.getElementById("post-editor-italics"); + const buttonStrike = document.getElementById("post-editor-strike"); + const buttonCode = document.getElementById("post-editor-code"); + + function insertTag(tagStart, newline = false) { + const tagEnd = tagStart; + const tagInsertStart = `[${tagStart}]${newline ? "\n" : ""}`; + const tagInsertEnd = `${newline ? "\n" : ""}[/${tagEnd}]`; + const hasSelection = ta.selectionStart !== ta.selectionEnd; + const text = ta.value; + if (hasSelection) { + const realStart = Math.min(ta.selectionStart, ta.selectionEnd); + const realEnd = Math.max(ta.selectionStart, ta.selectionEnd); + const selectionLength = realEnd - realStart; + + const strStart = text.slice(0, realStart); + const strEnd = text.substring(realEnd); + const frag = `${tagInsertStart}${text.slice(realStart, realEnd)}${tagInsertEnd}`; + const reconst = `${strStart}${frag}${strEnd}`; + ta.value = reconst; + ta.setSelectionRange(realStart + tagInsertStart.length, realStart + tagInsertStart.length + selectionLength); + ta.focus() + } else { + const cursor = ta.selectionStart; + const strStart = text.slice(0, cursor); + const strEnd = text.substr(cursor); + const newCursor = strStart.length + tagInsertStart.length; + const reconst = `${strStart}${tagInsertStart}${tagInsertEnd}${strEnd}`; + ta.value = reconst; + ta.setSelectionRange(newCursor, newCursor); + ta.focus() + } + } + + buttonBold.addEventListener("click", (e) => { + e.preventDefault(); + insertTag("b") + }) + buttonItalics.addEventListener("click", (e) => { + e.preventDefault(); + insertTag("i") + }) + buttonStrike.addEventListener("click", (e) => { + e.preventDefault(); + insertTag("s") + }) + buttonCode.addEventListener("click", (e) => { + e.preventDefault(); + insertTag("code", true) + }) +} diff --git a/js/thread.js b/js/thread.js index 84b17f0..05ba3fa 100644 --- a/js/thread.js +++ b/js/thread.js @@ -1,8 +1,10 @@ -const ta = document.getElementById("post_content"); +{ + const ta = document.getElementById("post_content"); -for (let button of document.querySelectorAll(".reply-button")) { - button.addEventListener("click", (e) => { - ta.value += button.value; - ta.scrollIntoView() - }) + for (let button of document.querySelectorAll(".reply-button")) { + button.addEventListener("click", (e) => { + ta.value += button.value; + ta.scrollIntoView() + }) + } } diff --git a/sass/style.scss b/sass/style.scss index d8650c4..df775ca 100644 --- a/sass/style.scss +++ b/sass/style.scss @@ -397,8 +397,14 @@ input[type="text"], input[type="password"], textarea, select { flex-direction: column; align-items: baseline; height: 100%; - - &>textarea{ - height: 100%; - } +} + +.babycode-editor { + height: 150px; +} + + +ul { + margin: 10px 0 10px 30px; + padding: 0; } diff --git a/views/common/babycode-editor-component.etlua b/views/common/babycode-editor-component.etlua new file mode 100644 index 0000000..cca723d --- /dev/null +++ b/views/common/babycode-editor-component.etlua @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/views/common/babycode-editor.etlua b/views/common/babycode-editor.etlua new file mode 100644 index 0000000..4289602 --- /dev/null +++ b/views/common/babycode-editor.etlua @@ -0,0 +1,16 @@ +<% + local save_button_text = "Post reply" + if cancel_url then + save_button_text = "Save" + end +%> +
"> + <% render ("views.common.babycode-editor-component", {ta_name = ta_name, prefill = prefill}) %> + + + <% if cancel_url then %> + Cancel + <% end %> + + <% render("views.common.bbcode_help") %> +
diff --git a/views/common/bbcode_help.etlua b/views/common/bbcode_help.etlua index 9ce4a25..5c9da65 100644 --- a/views/common/bbcode_help.etlua +++ b/views/common/bbcode_help.etlua @@ -1,5 +1,5 @@
- Supported babycode tags + babycode guide -
\ No newline at end of file + diff --git a/views/threads/create.etlua b/views/threads/create.etlua index ceb2609..a7cffe5 100644 --- a/views/threads/create.etlua +++ b/views/threads/create.etlua @@ -9,8 +9,8 @@
- - +
+ <% render("views.common.babycode-editor-component", {ta_name = "initial_post"}) %> <% render "views.common.bbcode_help" %> diff --git a/views/threads/post.etlua b/views/threads/post.etlua index 609015a..681ab63 100644 --- a/views/threads/post.etlua +++ b/views/threads/post.etlua @@ -54,13 +54,11 @@ <% if not edit then %> <%- post.content %> <% else %> -
- - - - ">Cancel - -
+ <% render("views.common.babycode-editor", { + cancel_url = url_for("thread", {slug = thread.slug}, {page = page}) .. "#post-" .. post.id, + prefill = post.original_markup, + ta_name = "new_content" + }) %> <% end %> diff --git a/views/threads/thread.etlua b/views/threads/thread.etlua index f98146e..0dd15bc 100644 --- a/views/threads/thread.etlua +++ b/views/threads/thread.etlua @@ -1,10 +1,6 @@ <% local is_locked = ntob(thread.is_locked) local can_post = (not is_locked and not me:is_guest()) or me:is_mod() - -- not locked, not guest, not mod = not false and not false or false = true and true or false = true - -- locked, not guest, not mod = not true and not false or false = false and true or false = false - -- not locked, guest, not mod = not false and not true or false = true and false or false = false - -- not locked, not guest, mod = not false and not false or true = true and true and true %>