forked from devs/PCv5
Improved the editor
This commit is contained in:
parent
8cd862078b
commit
6fe04b0a6c
|
@ -38,17 +38,18 @@ function editor_replace_range(textarea, start, end, contents)
|
|||
return [start, start + contents.length];
|
||||
}
|
||||
|
||||
/* Event handler that inserts the button's data-before and data-after
|
||||
attributes around the selection. */
|
||||
function editor_insert_around(event)
|
||||
/* Event handler that inserts specified tokens around the selection.
|
||||
after token is the same as before if not specified */
|
||||
function editor_insert_around(event, before="", after=null)
|
||||
{
|
||||
const [editor, button, ta] = editor_event_source(event);
|
||||
ta.focus();
|
||||
let indexStart = ta.selectionStart;
|
||||
let indexEnd = ta.selectionEnd;
|
||||
|
||||
const before = button.dataset.before || "";
|
||||
const after = button.dataset.after || "";
|
||||
if(after === null) {
|
||||
after = before;
|
||||
}
|
||||
|
||||
let [start, end] = editor_replace_range(ta, indexStart, indexEnd,
|
||||
before + ta.value.substring(indexStart, indexEnd) + after);
|
||||
|
@ -100,7 +101,8 @@ function editor_act_on_lines(event, fn)
|
|||
preview();
|
||||
}
|
||||
|
||||
function editor_clear_modals(event, close = true) {
|
||||
function editor_clear_modals(event, close = true)
|
||||
{
|
||||
// Stop the propagation of the event
|
||||
event.stopPropagation()
|
||||
|
||||
|
@ -120,6 +122,48 @@ function editor_clear_modals(event, close = true) {
|
|||
for (const i of modals) {i.style.display = 'none'};
|
||||
}
|
||||
|
||||
|
||||
/* End-user functions */
|
||||
function editor_inline(event, type)
|
||||
{
|
||||
tokens = {
|
||||
bold: "**",
|
||||
italic: "*",
|
||||
underline: "__",
|
||||
strike: "~~",
|
||||
inlinecode: "`",
|
||||
};
|
||||
|
||||
if(type in tokens){
|
||||
editor_insert_around(event, tokens[type]);
|
||||
}
|
||||
|
||||
preview();
|
||||
}
|
||||
|
||||
function editor_display_link_modal(event) {
|
||||
const [editor, button, ta] = editor_event_source(event);
|
||||
let indexStart = ta.selectionStart;
|
||||
let indexEnd = ta.selectionEnd;
|
||||
let selection = ta.value.substring(indexStart, indexEnd);
|
||||
|
||||
// Assuming it's a link
|
||||
if(selection.match(/^https?:\/\/\S+/)) {
|
||||
event.currentTarget.querySelector("#link-link-input").value = selection;
|
||||
}
|
||||
// Or text
|
||||
else if(selection != "") {
|
||||
event.currentTarget.querySelector("#link-desc-input").value = selection;
|
||||
}
|
||||
// Or nothing selected
|
||||
else {
|
||||
event.currentTarget.querySelector("#link-desc-input").value = "";
|
||||
event.currentTarget.querySelector("#link-link-input").value = "";
|
||||
}
|
||||
|
||||
event.currentTarget.children[1].style = {'display': 'block'};
|
||||
}
|
||||
|
||||
function editor_insert_link(event, link_id, text_id, media = false)
|
||||
{
|
||||
const [editor, button, ta] = editor_event_source(event);
|
||||
|
@ -155,7 +199,7 @@ function editor_insert_link(event, link_id, text_id, media = false)
|
|||
preview();
|
||||
}
|
||||
|
||||
function editor_set_title(event, level, diff)
|
||||
function editor_title(event, level, diff)
|
||||
{
|
||||
editor_act_on_lines(event, function(line) {
|
||||
/* Strip all the initial # (and count them) */
|
||||
|
@ -227,22 +271,41 @@ function editor_numbered_list(event)
|
|||
});
|
||||
}
|
||||
|
||||
function editor_table(event) {
|
||||
let table = `| Column 1 | Column 2 | Column 3 |
|
||||
| -------- | -------- | -------- |
|
||||
| Text | Text | Text |`;
|
||||
|
||||
editor_insert_around(event, "", table);
|
||||
}
|
||||
|
||||
function editor_separator(event) {
|
||||
editor_insert_around(event, "", "\n---\n");
|
||||
}
|
||||
|
||||
|
||||
previewTimeout = null;
|
||||
ta = document.querySelector(".editor textarea");
|
||||
ta.addEventListener('keydown', function(e) {
|
||||
// Tab insert some spaces
|
||||
// Ctrl+Enter send the form
|
||||
let keyCode = e.keyCode || e.which;
|
||||
if (keyCode == 9) {
|
||||
// TODO Add one tab to selected text without replacing it
|
||||
e.preventDefault();
|
||||
|
||||
|
||||
let start = e.target.selectionStart;
|
||||
let end = e.target.selectionEnd;
|
||||
// set textarea value to: text before caret + tab + text after caret
|
||||
e.target.value = e.target.value.substring(0, start) + "\t" + e.target.value.substring(end);
|
||||
e.target.selectionEnd = start + 1;
|
||||
}
|
||||
|
||||
// TODO
|
||||
// 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)) {
|
||||
|
|
|
@ -3,22 +3,22 @@
|
|||
<!-- Buttons for the text editor -->
|
||||
<div class="btn-group">
|
||||
<!-- Underline, Bold, Italic, Strikethrough -->
|
||||
<button type="button" onclick="editor_insert_around(event)" data-before="__" data-after="__" title="__Souligné__">
|
||||
<button type="button" onclick="editor_inline(event, 'underline')" title="__Souligné__">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M12 17c3.31 0 6-2.69 6-6V3h-2.5v8c0 1.93-1.57 3.5-3.5 3.5S8.5 12.93 8.5 11V3H6v8c0 3.31 2.69 6 6 6zm-7 2v2h14v-2H5z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button type="button" onclick="editor_insert_around(event)" data-before="**" data-after="**" title="**Gras**">
|
||||
<button type="button" onclick="editor_inline(event, 'bold')" title="**Gras**">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M15.6 10.79c.97-.67 1.65-1.77 1.65-2.79 0-2.26-1.75-4-4-4H7v14h7.04c2.09 0 3.71-1.7 3.71-3.79 0-1.52-.86-2.82-2.15-3.42zM10 6.5h3c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-3v-3zm3.5 9H10v-3h3.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button type="button" onclick="editor_insert_around(event)" data-before="*" data-after="*" title="*Italique*">
|
||||
<button type="button" onclick="editor_inline(event, 'italic')" title="*Italique*">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M10 4v3h2.21l-3.42 8H6v3h8v-3h-2.21l3.42-8H18V4z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button type="button" onclick="editor_insert_around(event)" data-before="~~" data-after="~~" title="~~Barré~~">
|
||||
<button type="button" onclick="editor_inline(event, 'strike')" title="~~Barré~~">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M6.85,7.08C6.85,4.37,9.45,3,12.24,3c1.64,0,3,0.49,3.9,1.28c0.77,0.65,1.46,1.73,1.46,3.24h-3.01 c0-0.31-0.05-0.59-0.15-0.85c-0.29-0.86-1.2-1.28-2.25-1.28c-1.86,0-2.34,1.02-2.34,1.7c0,0.48,0.25,0.88,0.74,1.21 C10.97,8.55,11.36,8.78,12,9H7.39C7.18,8.66,6.85,8.11,6.85,7.08z M21,12v-2H3v2h9.62c1.15,0.45,1.96,0.75,1.96,1.97 c0,1-0.81,1.67-2.28,1.67c-1.54,0-2.93-0.54-2.93-2.51H6.4c0,0.55,0.08,1.13,0.24,1.58c0.81,2.29,3.29,3.3,5.67,3.3 c2.27,0,5.3-0.89,5.3-4.05c0-0.3-0.01-1.16-0.48-1.94H21V12z"/>
|
||||
</svg>
|
||||
|
@ -26,27 +26,27 @@
|
|||
|
||||
<span class="separator"></span>
|
||||
<!-- Headers/Titles -->
|
||||
<button type="button" onclick="editor_set_title(event, 1, 0)" title="# Titre 1">
|
||||
<button type="button" onclick="editor_title(event, 1, 0)" title="# Titre 1">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M3,4H5V10H9V4H11V18H9V12H5V18H3V4M14,18V16H16V6.31L13.5,7.75V5.44L16,4H18V16H20V18H14Z" />
|
||||
</svg>
|
||||
</button>
|
||||
<button type="button" onclick="editor_set_title(event, 2, 0)" title="## Titre 2">
|
||||
<button type="button" onclick="editor_title(event, 2, 0)" title="## Titre 2">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M3,4H5V10H9V4H11V18H9V12H5V18H3V4M21,18H15A2,2 0 0,1 13,16C13,15.47 13.2,15 13.54,14.64L18.41,9.41C18.78,9.05 19,8.55 19,8A2,2 0 0,0 17,6A2,2 0 0,0 15,8H13A4,4 0 0,1 17,4A4,4 0 0,1 21,8C21,9.1 20.55,10.1 19.83,10.83L15,16H21V18Z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button type="button" onclick="editor_set_title(event, 3, 0)" title="### Titre 3">
|
||||
<button type="button" onclick="editor_title(event, 3, 0)" title="### Titre 3">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M3,4H5V10H9V4H11V18H9V12H5V18H3V4M15,4H19A2,2 0 0,1 21,6V16A2,2 0 0,1 19,18H15A2,2 0 0,1 13,16V15H15V16H19V12H15V10H19V6H15V7H13V6A2,2 0 0,1 15,4Z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button type="button" onclick="editor_set_title(event, 0, -1)" title="Réduire le niveau de titre">
|
||||
<button type="button" onclick="editor_title(event, 0, -1)" title="Réduire le niveau de titre">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M4,4H6V10H10V4H12V18H10V12H6V18H4V4M20.42,7.41L16.83,11L20.42,14.59L19,16L14,11L19,6L20.42,7.41Z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button type="button" onclick="editor_set_title(event, 0, +1)" title="Augmenter le niveau de titre">
|
||||
<button type="button" onclick="editor_title(event, 0, +1)" title="Augmenter le niveau de titre">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M4,4H6V10H10V4H12V18H10V12H6V18H4V4M14.59,7.41L18.17,11L14.59,14.59L16,16L21,11L16,6L14.59,7.41Z"/>
|
||||
</svg>
|
||||
|
@ -54,7 +54,7 @@
|
|||
|
||||
<span class="separator"></span>
|
||||
<!-- Code, Citations -->
|
||||
<button type="button" onclick="editor_insert_around(event)" data-before="`" data-after="`" title="`code`">
|
||||
<button type="button" onclick="editor_inline(event, 'inlinecode')" title="`code`">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0l4.6-4.6-4.6-4.6L16 6l6 6-6 6-1.4-1.4z"/>
|
||||
</svg>
|
||||
|
@ -82,17 +82,12 @@
|
|||
<span class="separator"></span>
|
||||
<!-- Table, Separators, Images, Link, Upload -->
|
||||
<!-- I need to find a way to replace the LF with \n -->
|
||||
<button type="button" onclick="editor_insert_around(event)" title="Tableau" data-after="
|
||||
| Column 1 | Column 2 | Column 3 |
|
||||
| -------- | -------- | -------- |
|
||||
| Text | Text | Text |">
|
||||
<button type="button" onclick="editor_table(event)" title="Tableau">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M3 3v18h18V3H3zm8 16H5v-6h6v6zm0-8H5V5h6v6zm8 8h-6v-6h6v6zm0-8h-6V5h6v6z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<button type="button" onclick="editor_insert_around(event)" data-before="
|
||||
---
|
||||
" title="Séparateur">
|
||||
<button type="button" onclick="editor_separator(event)" title="Séparateur">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<rect fill-rule="evenodd" height="2" width="16" x="4" y="11"/>
|
||||
</svg>
|
||||
|
@ -104,7 +99,7 @@
|
|||
</svg>
|
||||
</button>
|
||||
-->
|
||||
<button type="button" onclick="event.currentTarget.children[1].style = {'display': 'block'}" title="Lien">
|
||||
<button type="button" onclick="editor_display_link_modal(event)" title="Lien">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"/>
|
||||
</svg>
|
||||
|
|
Loading…
Reference in New Issue