Skip to content

Commit 3bb2995

Browse files
committed
markdown toolbar for textarea
1 parent c3b9ed3 commit 3bb2995

3 files changed

Lines changed: 134 additions & 25 deletions

File tree

public/comments/comments.css

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,4 +331,43 @@
331331
font-size: 14px;
332332
white-space: normal;
333333
padding: 1px 5px;
334-
}
334+
}
335+
336+
337+
338+
#kucos-root #markdown-editor #toolbar {
339+
overflow: hidden;
340+
margin-top: 20px;
341+
margin-bottom: -20px;
342+
width: 100%;
343+
}
344+
#kucos-root #markdown-editor #toolbar button {
345+
border: 1px solid transparent;
346+
background-color: #f6f6f6;
347+
border-radius: 5px;
348+
color: #555555;
349+
font-family: sans-serif;
350+
font-size: 0.8rem;
351+
cursor: pointer;
352+
padding: 0.2rem;
353+
min-width: 30px;
354+
}
355+
#kucos-root #markdown-editor #toolbar button:hover,
356+
#kucos-root #markdown-editor #toolbar button.active {
357+
border: 1px solid #c5c5c5;
358+
color: rgb(100, 100, 100);
359+
background-color: #f0f0f0;
360+
border-radius: 5px;
361+
outline: 0px;
362+
}
363+
#kucos-root #markdown-editor #toolbar button:focus {
364+
outline: none;
365+
}
366+
#kucos-root #markdown-editor #input-output #input-area:focus,
367+
#kucos-root #markdown-editor #input-output #input-area:active {
368+
outline: 0px;
369+
}
370+
371+
#input-area {
372+
width: 100%
373+
}

public/comments/comments.js

Lines changed: 91 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ class Comments {
77
bindEvents = () => {
88
this.on(document.getElementById("submitComment"), 'click', this.postComment);
99
this.on(document.getElementById("commentsArea"), 'click', this.commentsArea);
10+
this.on(document.getElementById("toolbar"), 'click', this.toolbar);
1011
};
1112

1213
on = (element, event, func) => {
@@ -253,17 +254,30 @@ class Comments {
253254
}
254255

255256
let formArea = `
256-
<form id="_comment_form">
257-
<textarea data-autoresize id="comment-area${idinput}" placeholder="${text}"></textarea>
258-
<br />
259-
<input type="hidden" id="username${idinput}" placeholder="Your username">
260-
<input type="text" id="author${idinput}" placeholder="Your name (optional)">
261-
<input type="email" id="email${idinput}" placeholder="Your email (optional)">
262-
<input type="website" id="website${idinput}" placeholder="Your website (optional)">
263-
${input}
264-
</form>
265-
<div id="_infos${idinput}"></div>`;
266-
257+
<div id="markdown-editor">
258+
<div id="toolbar">
259+
<button id="bold${idinput}-t">B</button>
260+
<button id="italic${idinput}-t">I</button>
261+
<button id="quote${idinput}-t">quote</button>
262+
<button id="link${idinput}-t">link</button>
263+
<button id="code${idinput}-t">code</button>
264+
<button id="spoiler${idinput}-t">spoiler</button>
265+
<button id="delete${idinput}-t">del</button>
266+
</div>
267+
<div id="input-output">
268+
<form id="_comment_form">
269+
<textarea data-autoresize id="comment-area${idinput}" placeholder="${text}"></textarea>
270+
<br />
271+
<input type="hidden" id="username${idinput}" placeholder="Your username">
272+
<input type="text" id="author${idinput}" placeholder="Your name (optional)">
273+
<input type="email" id="email${idinput}" placeholder="Your email (optional)">
274+
<input type="website" id="website${idinput}" placeholder="Your website (optional)">
275+
${input}
276+
</form>
277+
<div id="_infos${idinput}"></div>
278+
</div>
279+
</div>`;
280+
267281
return formArea;
268282
};
269283

@@ -278,9 +292,9 @@ class Comments {
278292

279293
if (event.target.nodeName === 'A' || event.target.nodeName === 'BUTTON' || event.target.nodeName === 'LABEL') {
280294
let parts = event.target.id.split("-");
281-
let type = parts[0];
282-
let id = parts[parts.length-1];
283-
let eid = event.target.id.split("reply-")[1];
295+
let type = parts[0];
296+
let id = parts[1];
297+
let toolbar = parts[2];
284298
let prevChild = document.getElementById(`childlist-${id}`);
285299

286300
if (type == 'reply' || type == 'edit') {
@@ -325,12 +339,75 @@ class Comments {
325339
this.vote(id, type);
326340
} else if(type == 'checker') {
327341
document.getElementById("checker-" + id).checked = true;
342+
} else if( toolbar == "t" && id ) {
343+
this.toolbar(null, type, "comment-area-"+id)
328344
}
329345

330346
}
331347

332348
};
333349

350+
toolbar = (event=null, button, area) => {
351+
352+
if (event) {
353+
let parts = event.target.id.split("-");
354+
button = parts[0];
355+
var textarea = document.getElementById( 'comment-area' );
356+
} else {
357+
var textarea = document.getElementById( area );
358+
}
359+
360+
if (button == "bold") {
361+
insertText( textarea, '****', 'bold', 2, 6 )
362+
363+
} else if (button == "italic") {
364+
insertText( textarea, '__', 'italic', 1, 7 )
365+
366+
} else if (button == "quote") {
367+
insertText( textarea, '\n>', ' quote\n', 3, 8 )
368+
369+
} else if (button == "link") {
370+
insertText( textarea, '[](http://...)', 'url text', 1, 9 )
371+
372+
} else if (button == "code") {
373+
insertText( textarea, '``', 'code', 1, 5 )
374+
375+
} else if (button == "spoiler") {
376+
insertText( textarea, '\n!', ' spoiler\n', 3, 10 )
377+
378+
} else if (button == "delete") {
379+
insertText( textarea, '~~~~', 'delete text', 2, 13 )
380+
381+
}
382+
383+
function insertText( textarea, syntax, placeholder = 'demo', selectionStart = 0, selectionEnd = 0 ) {
384+
// Current Selection
385+
const currentSelectionStart = textarea.selectionStart;
386+
const currentSelectionEnd = textarea.selectionEnd;
387+
const currentText = textarea.value;
388+
389+
if( currentSelectionStart === currentSelectionEnd ) {
390+
const textWithSyntax = textarea.value = currentText.substring( 0, currentSelectionStart ) + syntax + currentText.substring( currentSelectionEnd );
391+
textarea.value = textWithSyntax.substring( 0, currentSelectionStart + selectionStart ) + placeholder + textWithSyntax.substring( currentSelectionStart + selectionStart )
392+
393+
textarea.focus();
394+
textarea.selectionStart = currentSelectionStart + selectionStart;
395+
textarea.selectionEnd = currentSelectionEnd + selectionEnd;
396+
} else {
397+
const selectedText = currentText.substring( currentSelectionStart, currentSelectionEnd );
398+
const withoutSelection = currentText.substring( 0, currentSelectionStart ) + currentText.substring( currentSelectionEnd );
399+
const textWithSyntax = withoutSelection.substring( 0, currentSelectionStart ) + syntax + withoutSelection.substring( currentSelectionStart );
400+
401+
// Surround selected text
402+
textarea.value = textWithSyntax.substring( 0, currentSelectionStart + selectionStart ) + selectedText + textWithSyntax.substring( currentSelectionStart + selectionStart );
403+
404+
textarea.focus();
405+
textarea.selectionEnd = currentSelectionEnd + selectionStart + selectedText.length;
406+
}
407+
}
408+
409+
};
410+
334411
request = async (body=null, method, param) => {
335412
let kucosServerUrl = "http://localhost:3000";
336413

vercel.json

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
11
{
22
"name": "kucos",
33
"version": 2,
4-
"builds": [
5-
{ "src": "/public/min/**", "use": "@now/static" },
6-
{ "src": "/index.js", "use": "@now/node-server" }
7-
],
8-
"routes": [
9-
{ "src": "/min/(.*)", "dest": "/public/min/$1" },
10-
{ "src": "/(.*)", "dest": "/index.js" }
11-
]
12-
}
13-
4+
"builds": [{ "src": "index.js", "use": "@vercel/node" }],
5+
"routes": [{ "src": "/(.*)", "dest": "/index.js" }]
6+
}

0 commit comments

Comments
 (0)