Compare commits
2 Commits
e7260090ac
...
66318698e5
Author | SHA1 | Date | |
---|---|---|---|
66318698e5 | |||
ec3f144b4e |
@ -394,6 +394,12 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus
|
|||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
.post-edit-form > textarea {
|
|
||||||
height: 100%;
|
.babycode-editor {
|
||||||
|
height: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
margin: 10px 0 10px 30px;
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
54
js/post-editor.js
Normal file
54
js/post-editor.js
Normal file
@ -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)
|
||||||
|
})
|
||||||
|
}
|
10
js/thread.js
Normal file
10
js/thread.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
const ta = document.getElementById("post_content");
|
||||||
|
|
||||||
|
for (let button of document.querySelectorAll(".reply-button")) {
|
||||||
|
button.addEventListener("click", (e) => {
|
||||||
|
ta.value += button.value;
|
||||||
|
ta.scrollIntoView()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@ -397,8 +397,14 @@ input[type="text"], input[type="password"], textarea, select {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
}
|
||||||
&>textarea{
|
|
||||||
height: 100%;
|
.babycode-editor {
|
||||||
}
|
height: 150px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ul {
|
||||||
|
margin: 10px 0 10px 30px;
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
8
views/common/babycode-editor-component.etlua
Normal file
8
views/common/babycode-editor-component.etlua
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<span>
|
||||||
|
<button type=button id="post-editor-bold" title="Insert Bold">B</button>
|
||||||
|
<button type=button id="post-editor-italics" title="Insert Italics">I</button>
|
||||||
|
<button type=button id="post-editor-strike" title="Insert Strikethrough">S</button>
|
||||||
|
<button type=button id="post-editor-code" title="Insert Code block">Code</button>
|
||||||
|
</span>
|
||||||
|
<textarea class="babycode-editor" name="<%= ta_name %>" id="post_content" placeholder="Post body" required><%- prefill or "" %></textarea>
|
||||||
|
<script src="/static/js/post-editor.js"></script>
|
16
views/common/babycode-editor.etlua
Normal file
16
views/common/babycode-editor.etlua
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<%
|
||||||
|
local save_button_text = "Post reply"
|
||||||
|
if cancel_url then
|
||||||
|
save_button_text = "Save"
|
||||||
|
end
|
||||||
|
%>
|
||||||
|
<form class="post-edit-form" method="post" action="<%= url or "" %>">
|
||||||
|
<% render ("views.common.babycode-editor-component", {ta_name = ta_name, prefill = prefill}) %>
|
||||||
|
<span>
|
||||||
|
<input type=submit value="<%= save_button_text %>">
|
||||||
|
<% if cancel_url then %>
|
||||||
|
<a class="linkbutton warn" href="<%= cancel_url %>">Cancel</a>
|
||||||
|
<% end %>
|
||||||
|
</span>
|
||||||
|
<% render("views.common.bbcode_help") %>
|
||||||
|
</form>
|
@ -1,5 +1,5 @@
|
|||||||
<details>
|
<details>
|
||||||
<summary>Supported babycode tags</summary>
|
<summary>babycode guide</summary>
|
||||||
<ul>
|
<ul>
|
||||||
<li>[b]<b>bold</b>[/b]</li>
|
<li>[b]<b>bold</b>[/b]</li>
|
||||||
<li>[i]<i>italic</i>[/i]</li>
|
<li>[i]<i>italic</i>[/i]</li>
|
||||||
@ -8,4 +8,4 @@
|
|||||||
<li>[url]<a href="https://unlabeled-url.example.com">https://unlabeled-url.example.com</a>[/url]</li>
|
<li>[url]<a href="https://unlabeled-url.example.com">https://unlabeled-url.example.com</a>[/url]</li>
|
||||||
<li>[code]<code>code block</code>[/code]</li>
|
<li>[code]<code>code block</code>[/code]</li>
|
||||||
</ul>
|
</ul>
|
||||||
</details>
|
</details>
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
</select><br>
|
</select><br>
|
||||||
<label for="title">Thread title</label>
|
<label for="title">Thread title</label>
|
||||||
<input type="text" id="title" name="title" placeholder="Required" required>
|
<input type="text" id="title" name="title" placeholder="Required" required>
|
||||||
<label for="initial_post">Post body</label>
|
<label for="initial_post">Post body</label><br>
|
||||||
<textarea id="initial_post" name="initial_post" placeholder="Required" rows=5 required></textarea>
|
<% render("views.common.babycode-editor-component", {ta_name = "initial_post"}) %>
|
||||||
<% render "views.common.bbcode_help" %>
|
<% render "views.common.bbcode_help" %>
|
||||||
<input type="submit" value="Create thread">
|
<input type="submit" value="Create thread">
|
||||||
</form>
|
</form>
|
||||||
|
@ -43,8 +43,10 @@
|
|||||||
show_reply = false
|
show_reply = false
|
||||||
end
|
end
|
||||||
if show_reply then
|
if show_reply then
|
||||||
|
local d = post.created_at < post.edited_at and post.edited_at or post.created_at
|
||||||
|
local reply_text = ("On %s, %s said:\n%s\n\n---\n\n"):format(os.date("%c", d), post.username, post.original_markup)
|
||||||
%>
|
%>
|
||||||
<button>Reply</button>
|
<button value="<%= reply_text %>" class="reply-button">Reply</button>
|
||||||
<% end %>
|
<% end %>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@ -52,13 +54,11 @@
|
|||||||
<% if not edit then %>
|
<% if not edit then %>
|
||||||
<%- post.content %>
|
<%- post.content %>
|
||||||
<% else %>
|
<% else %>
|
||||||
<form class="post-edit-form" method="post">
|
<% render("views.common.babycode-editor", {
|
||||||
<textarea name="new_content" required><%- post.original_markup %></textarea>
|
cancel_url = url_for("thread", {slug = thread.slug}, {page = page}) .. "#post-" .. post.id,
|
||||||
<span>
|
prefill = post.original_markup,
|
||||||
<input type=submit value="Save">
|
ta_name = "new_content"
|
||||||
<a class="linkbutton warn" href="<%= url_for("thread", {slug = thread.slug}, {page = page}) .. "#post-" .. post.id %>">Cancel</a>
|
}) %>
|
||||||
</span>
|
|
||||||
</form>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
<% local is_locked = ntob(thread.is_locked) %>
|
<%
|
||||||
|
local is_locked = ntob(thread.is_locked)
|
||||||
|
local can_post = (not is_locked and not me:is_guest()) or me:is_mod()
|
||||||
|
%>
|
||||||
<main>
|
<main>
|
||||||
<nav class="darkbg">
|
<nav class="darkbg">
|
||||||
<h1 class="thread-title"><%= thread.title %></h1>
|
<h1 class="thread-title"><%= thread.title %></h1>
|
||||||
@ -16,10 +19,8 @@
|
|||||||
<% if is_locked then -%>
|
<% if is_locked then -%>
|
||||||
<% render("views.common.infobox", {kind = constants.InfoboxKind.LOCK, msg = "This thread is locked."}) %>
|
<% render("views.common.infobox", {kind = constants.InfoboxKind.LOCK, msg = "This thread is locked."}) %>
|
||||||
<% end -%>
|
<% end -%>
|
||||||
<% if not me:is_guest() and not is_locked then %>
|
<% if can_post then %>
|
||||||
<h1>Respond to "<%= thread.title %>"</h1>
|
<h1>Respond to "<%= thread.title %>"</h1>
|
||||||
<form method="post">
|
<% render("views.common.babycode-editor", {ta_name="post_content"}) %>
|
||||||
<textarea id="post_content" name="post_content" placeholder="Response body" required></textarea><br>
|
<script src="/static/js/thread.js"></script>
|
||||||
<input type="submit" value="Post reply">
|
|
||||||
</form>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
Loading…
Reference in New Issue
Block a user