core: introduce new markdown input

To fix
* Avoid blinking in preview
* Don't insert stupid space on empty textarea
This commit is contained in:
Antoine Bartuccio 2018-12-14 16:24:11 +01:00
parent acfbdd1ad5
commit 775f456c40
4 changed files with 10444 additions and 13 deletions

File diff suppressed because one or more lines are too long

10362
core/static/core/simplemde/simplemde.min.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,62 @@
<div>
<textarea name="{{ widget.name }}"{% include "django/forms/widgets/attrs.html" %}>
{% if widget.value %}{{ widget.value }}{% endif %}</textarea>
{# The simplemde script can be included twice, it's safe in the code #}
<script src="{{ statics.js }}"> </script>
<script type="text/javascript">
var css = "{{ statics.css }}";
// Only import the css once
if (!document.head.innerHTML.includes(css)){
document.head.innerHTML += '<link rel="stylesheet" href="' + css + '">';
}
// You can't get the csrf token from the template in a widget
// We get it from a cookie as a workaround, see this link
// https://docs.djangoproject.com/en/2.0/ref/csrf/#ajax
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = jQuery.trim(cookies[i]);
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
// Custom markdown parser
function customMarkdownParser(plainText, preview) {
// Wait for jquery to load
var waitForJquery = setInterval(function () {
if (typeof $ != 'undefined'){
clearInterval(waitForJquery)
$.ajax({
url: "{{ markdown_api_url }}",
method: "POST",
data: { text: plainText, csrfmiddlewaretoken: getCookie('csrftoken') },
}).done(function (msg) {
preview.innerHTML = msg;
});
}
}, 10);
}
// Pretty markdown input
var simplemde = new SimpleMDE({
element: document.getElementById("{{ widget.attrs.id }}"),
spellChecker: false,
previewRender: function(plainText, preview){ // Async method
customMarkdownParser(plainText, preview);
}
});
</script>
</div>

View File

@ -26,6 +26,8 @@ from django.contrib.auth.forms import UserCreationForm, AuthenticationForm
from django import forms from django import forms
from django.conf import settings from django.conf import settings
from django.db import transaction from django.db import transaction
from django.templatetags.static import static
from django.core.urlresolvers import reverse
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.forms import ( from django.forms import (
CheckboxSelectMultiple, CheckboxSelectMultiple,
@ -90,19 +92,17 @@ class SelectDate(DateInput):
class MarkdownInput(Textarea): class MarkdownInput(Textarea):
def render(self, name, value, attrs=None): template_name = "core/markdown_textarea.jinja"
output = (
'<p><a href="%(syntax_url)s">%(help_text)s</a></p>' def get_context(self, name, value, attrs):
'<div class="markdown_editor">%(content)s</div>' context = super(MarkdownInput, self).get_context(name, value, attrs)
% {
"syntax_url": Page.get_page_by_full_name( context["statics"] = {
settings.SITH_CORE_PAGE_SYNTAX "js": static("core/simplemde/simplemde.min.js"),
).get_absolute_url(), "css": static("core/simplemde/simplemde.min.css"),
"help_text": _("Help on the syntax"),
"content": super(MarkdownInput, self).render(name, value, attrs),
} }
) context["markdown_api_url"] = reverse("api:api_markdown")
return output return context
class SelectFile(TextInput): class SelectFile(TextInput):