add babycode button controls

This commit is contained in:
2026-05-28 07:50:47 +03:00
parent 160629fca7
commit ed395a0175
2 changed files with 66 additions and 10 deletions

View File

@@ -98,20 +98,21 @@
{%- if idx == 0 -%}
<span class="babycode-editor-controls">
<span class="button-row js-only" data-r="enhance">
<button type="button" class="minimal" data-babycode-tag="b" data-s="insertBabycode"><b>B</b></button>
<button type="button" class="minimal" data-babycode-tag="i" data-s="insertBabycode"><i>i</i></button>
<button type="button" class="minimal" data-babycode-tag="s" data-s="insertBabycode"><s>S</s></button>
<button type="button" class="minimal" data-babycode-tag="u" data-s="insertBabycode"><u>U</u></button>
<button type="button" class="minimal" data-babycode-tag="url" data-s="insertBabycode"><code>://</code></button>
<button type="button" class="minimal" data-babycode-tag="code" data-s="insertBabycode"><code>&lt;/&gt;</code></button>
<button type="button" class="minimal" data-babycode-tag="ol" data-s="insertBabycode">1.</button>
<button type="button" class="minimal" data-babycode-tag="ul" data-s="insertBabycode">&bullet;</button>
<button type="button" class="minimal"><img src="/static/emoji/angry.png" class="emoji"></button>
<button type="button" title="insert bold" class="minimal" data-babycode-tag="b" data-s="insertBabycode"><b>B</b></button>
<button type="button" title="insert italic" class="minimal" data-babycode-tag="i" data-s="insertBabycode"><i>i</i></button>
<button type="button" title="insert strikethrough" class="minimal" data-babycode-tag="s" data-s="insertBabycode"><s>S</s></button>
<button type="button" title="insert underline" class="minimal" data-babycode-tag="u" data-s="insertBabycode"><u>U</u></button>
<button type="button" title="insert link" class="minimal" data-babycode-tag="url" data-prefill="link label" data-s="insertBabycode"><code>://</code></button>
<button type="button" title="insert code block" class="minimal" data-babycode-tag="code" data-break-line data-s="insertBabycode"><code>&lt;/&gt;</code></button>
<button type="button" title="insert ordered list" class="minimal" data-babycode-tag="ol" data-break-line data-s="insertBabycode">1.</button>
<button type="button" title="insert unordered list" class="minimal" data-babycode-tag="ul" data-break-line data-s="insertBabycode">&bullet;</button>
<button type="button" title="insert spoiler" class="minimal" data-babycode-tag="spoiler=" data-break-line data-prefill="spoiler content" data-s="insertBabycode">s</button>
<button type="button" title="insert emoji&hellip;" class="minimal"><img src="/static/emoji/angry.png" class="emoji"></button>
</span>
<span class="flex-last">{# stub: char count #}</span>
</span>
<input type="hidden" name="babycode_banned_tags" id="{{id}}-banned-tags" value="{{banned_tags | unique | list | tojson | forceescape}}">
<textarea name="babycode_content" id="{{id}}" class="babycode-editor" placeholder="{{placeholder}}" {{'required' if required else ''}} autocomplete="off" maxlength="5000">{{ prefill }}</textarea>
<textarea name="babycode_content" id="{{id}}" class="babycode-editor" placeholder="{{placeholder}}" {{'required' if required else ''}} autocomplete="off" maxlength="5000" data-r="insertBabycode">{{ prefill }}</textarea>
{%- if banned_tags -%}
<div>
<span>Forbidden tags:</span>

View File

@@ -23,3 +23,58 @@ export function setTab(_, sender, el) {
}
}
}
export function insertBabycode(_, sender, el) {
if (!el.parentNode.contains(sender)) {
return;
}
const tagStart = sender.dataset.babycodeTag;
const breakLine = 'breakLine' in sender.dataset;
const prefill = 'prefill' in sender.dataset ? sender.dataset.prefill : '';
const hasAttr = tagStart[tagStart.length - 1] === '=';
let tagEnd = tagStart;
let tagInsertStart = `[${tagStart}]${breakLine ? '\n' : ''}`;
if (hasAttr) {
tagEnd = tagEnd.slice(0, -1);
}
const tagInsertEnd = `${breakLine ? '\n' : ''}[/${tagEnd}]`;
const hasSelection = el.selectionStart !== el.selectionEnd;
const text = el.value;
if (hasSelection) {
const realStart = Math.min(el.selectionStart, el.selectionEnd);
const realEnd = Math.max(el.selectionStart, el.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}`;
el.value = reconst;
if (!hasAttr) {
el.setSelectionRange(realStart + tagInsertStart.length, realStart + tagInsertEnd.length + selectionLength - 1);
} else {
const attrCursor = realStart + tagInsertEnd.length - (1 + (breakLine ? 1 : 0))
el.setSelectionRange(attrCursor, attrCursor); // cursor on attr
}
} else {
if (hasAttr) {
tagInsertStart += prefill;
}
const cursor = el.selectionStart;
const strStart = text.slice(0, cursor);
const strEnd = text.substring(cursor);
let newCursor = strStart.length + tagInsertStart.length;
if (hasAttr) {
newCursor = cursor + tagInsertStart.length - prefill.length - (1 + (breakLine ? 1 : 0)); //cursor on attr
}
const reconst = `${strStart}${tagInsertStart}${tagInsertEnd}${strEnd}`;
el.value = reconst;
el.setSelectionRange(newCursor, newCursor);
}
el.focus();
}