diff --git a/app/blueprints/api/endpoints.py b/app/blueprints/api/endpoints.py
index e37454f..266bf93 100644
--- a/app/blueprints/api/endpoints.py
+++ b/app/blueprints/api/endpoints.py
@@ -19,8 +19,10 @@ from flask import *
from flask_user import *
from . import bp
from .auth import is_api_authd
+from app import csrf
from app.models import *
from app.utils import is_package_page
+from app.markdown import render_markdown
from app.querybuilder import QueryBuilder
@bp.route("/api/packages/")
@@ -107,3 +109,9 @@ def whoami(token):
return jsonify({ "is_authenticated": False, "username": None })
else:
return jsonify({ "is_authenticated": True, "username": token.owner.username })
+
+
+@bp.route("/api/markdown/", methods=["POST"])
+@csrf.exempt
+def clean_markdown():
+ return render_markdown(request.data.decode("utf-8"))
diff --git a/app/public/static/markdowntextarea.js b/app/public/static/markdowntextarea.js
new file mode 100644
index 0000000..c2ba345
--- /dev/null
+++ b/app/public/static/markdowntextarea.js
@@ -0,0 +1,34 @@
+$("textarea.markdown").each(function() {
+ async function render(plainText, preview) {
+ const response = await fetch(new Request("/api/markdown/", {
+ method: "POST",
+ credentials: "same-origin",
+ body: plainText,
+ headers: {
+ "Accept": "text/html; charset=UTF-8",
+ },
+ }));
+
+ preview.innerHTML = await response.text();
+ }
+
+ let timeout_id = null;
+
+ new EasyMDE({
+ element: this,
+ hideIcons: ["image"],
+ forceSync: true,
+ previewRender: (plainText, preview) => {
+ if (timeout_id) {
+ clearTimeout(timeout_id);
+ }
+
+ timeout_id = setTimeout(() => {
+ render(plainText, preview);
+ timeout_id = null;
+ }, 500);
+
+ return preview.innerHTML;
+ }
+ });
+})
diff --git a/app/templates/base.html b/app/templates/base.html
index df10208..cfe2dfc 100644
--- a/app/templates/base.html
+++ b/app/templates/base.html
@@ -148,12 +148,9 @@
-
+
+
{% block scriptextra %}{% endblock %}