From ed1a534aa659660f79baf2efd7f43f377ff7b01d Mon Sep 17 00:00:00 2001 From: Eragon Date: Sun, 14 May 2023 23:13:55 +0200 Subject: [PATCH] editor: Add keybinds --- app/static/css/editor.css | 2 +- app/static/scripts/editor.js | 91 ++++++++++++++++++++----------- app/templates/widgets/editor.html | 2 +- 3 files changed, 60 insertions(+), 35 deletions(-) diff --git a/app/static/css/editor.css b/app/static/css/editor.css index fe41799..60383c4 100644 --- a/app/static/css/editor.css +++ b/app/static/css/editor.css @@ -4,7 +4,7 @@ flex-wrap: wrap; align-items: flex-end; } -.editor .btn-group .filler { +.editor .btn-group #filler { flex-grow: 1; } .editor .btn-group button { diff --git a/app/static/scripts/editor.js b/app/static/scripts/editor.js index 5074f3c..d47f216 100644 --- a/app/static/scripts/editor.js +++ b/app/static/scripts/editor.js @@ -11,17 +11,21 @@ function editor_event_source(event) /* Grab the button and the parent editor block. The onclick event itself usually reports the SVG in the button as the source */ let node = event.target || event.srcElement; - while(node != document.body) { - if(node.tagName == "BUTTON" && !button) { + while (node != document.body) { + if (node.tagName == "BUTTON" && !button) { button = node; } - if(node.classList.contains("editor") && !editor) { + if (node.classList.contains("editor") && !editor) { editor = node; + // Hack to use keybinds + if (!button) { + button = node.firstElementChild.firstElementChild + } break; } node = node.parentNode; } - if(!button || !editor) return; + if (!button || !editor) return; const ta = editor.querySelector(".editor textarea"); return [editor, button, ta]; @@ -47,7 +51,7 @@ function editor_insert_around(event, before="", after=null) let indexStart = ta.selectionStart; let indexEnd = ta.selectionEnd; - if(after === null) { + if (after === null) { after = before; } @@ -55,7 +59,7 @@ function editor_insert_around(event, before="", after=null) before + ta.value.substring(indexStart, indexEnd) + after); /* Restore selection */ - if(indexStart != indexEnd) { + if (indexStart != indexEnd) { ta.selectionStart = start; ta.selectionEnd = end; } @@ -76,13 +80,13 @@ function editor_act_on_lines(event, fn) let indexEnd = ta.selectionEnd; let firstLineIndex = ta.value.substring(0, indexStart).lastIndexOf('\n'); - if(firstLineIndex < 0) + if (firstLineIndex < 0) firstLineIndex = 0; else firstLineIndex += 1; let lastLineIndex = ta.value.substring(indexEnd).indexOf('\n'); - if(lastLineIndex < 0) + if (lastLineIndex < 0) lastLineIndex = ta.value.length; else lastLineIndex += indexEnd; @@ -124,7 +128,7 @@ function editor_clear_modals(event, close = true) /* End-user functions */ -function editor_inline(event, type) +function editor_inline(event, type, enable_preview = true) { tokens = { bold: "**", @@ -134,11 +138,13 @@ function editor_inline(event, type) inlinecode: "`", }; - if(type in tokens){ + if (type in tokens) { editor_insert_around(event, tokens[type]); } - preview(); + if (enable_preview) { + preview(); + } } function editor_display_link_modal(event) { @@ -148,11 +154,11 @@ function editor_display_link_modal(event) { let selection = ta.value.substring(indexStart, indexEnd); // Assuming it's a link - if(selection.match(/^https?:\/\/\S+/)) { + if (selection.match(/^https?:\/\/\S+/)) { event.currentTarget.querySelector("#link-link-input").value = selection; } // Or text - else if(selection != "") { + else if (selection != "") { event.currentTarget.querySelector("#link-desc-input").value = selection; } // Or nothing selected @@ -177,7 +183,7 @@ function editor_insert_link(event, link_id, text_id, media = false) const media_selector = document.getElementsByName("media-type"); for(i = 0; i < media_selector.length; i++) { - if(media_selector[i].checked) { + if (media_selector[i].checked) { media_type = `{type=${media_selector[i].value}}`; } } @@ -188,7 +194,7 @@ function editor_insert_link(event, link_id, text_id, media = false) `${media ? "!" : ""}[${text.length === 0 ? ta.value.substring(indexStart, indexEnd) : text}](${link})${media ? media_type : ""}`); /* Restore selection */ - if(indexStart != indexEnd) { + if (indexStart != indexEnd) { ta.selectionStart = start; ta.selectionEnd = end; } @@ -207,18 +213,18 @@ function editor_title(event, level, diff) while(count < line.length && line[count] == '#') count++; let contents_index = count; - if(count < line.length && line[count] == ' ') contents_index++; + if (count < line.length && line[count] == ' ') contents_index++; let contents = line.slice(contents_index); - if(level > 0 || count == 1 && diff == -1) { + if (level > 0 || count == 1 && diff == -1) { /* Remove the title if the corresponding level is re-requested */ - if(count == level || count == 1 && diff == -1) + if (count == level || count == 1 && diff == -1) return contents; /* Otherwise, add it */ else return '#'.repeat(level) + ' ' + contents; } - else if(count > 0) { + else if (count > 0) { /* Apply the difference */ let new_level = Math.max(1, Math.min(6, count + diff)); return '#'.repeat(new_level) + ' ' + contents; @@ -235,7 +241,7 @@ function editor_quote(event) while(count < line.length && line[count] == '>') count++; let contents_index = count; - if(count < line.length && line[count] == ' ') contents_index++; + if (count < line.length && line[count] == ' ') contents_index++; let contents = line.slice(contents_index); /* Apply the difference */ @@ -251,7 +257,7 @@ function editor_bullet_list(event) let count = ident.length; const contents = line.slice(count); - if((count < line.length || count == 0) && line[count] != '-') return '- ' + contents; + if ((count < line.length || count == 0) && line[count] != '-') return '- ' + contents; return ident + "\t" + contents; }); @@ -265,7 +271,7 @@ function editor_numbered_list(event) let count = ident.length; const contents = line.slice(count); - if((count < line.length || count == 0) && isNaN(line[count])) return '1. ' + contents; + if ((count < line.length || count == 0) && isNaN(line[count])) return '1. ' + contents; return ident + "\t" + contents; }); @@ -334,24 +340,43 @@ ta.addEventListener('keydown', function(e) { // Ctrl+B adds bold // Ctrl+I adds italic // Ctrl+U adds underline - + // Ctrl+Enter send the form - if (e.ctrlKey && keyCode == 13) { - let t = e.target; - while(! (t instanceof HTMLFormElement)) { - t = t.parentNode; - } - try { - t.submit(); - } catch(exception) { - t.submit.click(); + if (e.ctrlKey) { + switch (keyCode) { + case 13: + let t = e.target; + while(! (t instanceof HTMLFormElement)) { + t = t.parentNode; + } + try { + t.submit(); + } catch(exception) { + t.submit.click(); + } + break; + case 66: // B + editor_inline(e, "bold", false); + break; + case 72: // H + editor_title(e, 0, +1); + break; + case 73: // I + editor_inline(e, "italic", false); + break; + case 83: // S + editor_inline(e, "strike", false); + break; + case 85: // U + editor_inline(e, "underline", false); + break; } } // Set a timeout for refreshing the preview if (previewTimeout != null) { clearTimeout(previewTimeout); - } + } previewTimeout = setTimeout(preview, 3000); }); diff --git a/app/templates/widgets/editor.html b/app/templates/widgets/editor.html index 400af6d..32bfba9 100644 --- a/app/templates/widgets/editor.html +++ b/app/templates/widgets/editor.html @@ -154,7 +154,7 @@ --> -
+
Aide