Add markdown utils

- External links open in a new tab
- Clicking on image open an image modal
This commit is contained in:
cuom1999 2024-06-06 21:17:11 -05:00
parent a75a080b9c
commit d7cc620a0a
12 changed files with 51 additions and 16 deletions

View file

@ -33,6 +33,7 @@ SITE_ID = 1
SITE_NAME = "LQDOJ" SITE_NAME = "LQDOJ"
SITE_LONG_NAME = "LQDOJ: Le Quy Don Online Judge" SITE_LONG_NAME = "LQDOJ: Le Quy Don Online Judge"
SITE_ADMIN_EMAIL = False SITE_ADMIN_EMAIL = False
SITE_DOMAIN = "lqdoj.edu.vn"
DMOJ_REQUIRE_STAFF_2FA = True DMOJ_REQUIRE_STAFF_2FA = True

View file

@ -3,6 +3,8 @@ import bleach
from django.utils.html import escape from django.utils.html import escape
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from pymdownx import superfences from pymdownx import superfences
from django.conf import settings
from urllib.parse import urlparse
from judge.markdown_extensions import YouTubeExtension, EmoticonExtension from judge.markdown_extensions import YouTubeExtension, EmoticonExtension
@ -96,6 +98,35 @@ ALLOWED_ATTRS = [
] ]
def _wrap_img_iframe_with_lazy_load(soup):
for img in soup.findAll("img"):
if img.get("src"):
img["loading"] = "lazy"
for img in soup.findAll("iframe"):
if img.get("src"):
img["loading"] = "lazy"
return soup
def _wrap_images_with_featherlight(soup):
for img in soup.findAll("img"):
if img.get("src"):
link = soup.new_tag("a", href=img["src"], **{"data-featherlight": "image"})
img.wrap(link)
return soup
def _open_external_links_in_new_tab(soup):
domain = settings.SITE_DOMAIN.lower()
for a in soup.findAll("a", href=True):
href = a["href"]
if href.startswith("http://") or href.startswith("https://"):
link_domain = urlparse(href).netloc.lower()
if link_domain != domain:
a["target"] = "_blank"
return soup
def markdown(value, lazy_load=False): def markdown(value, lazy_load=False):
extensions = EXTENSIONS extensions = EXTENSIONS
html = _markdown.markdown( html = _markdown.markdown(
@ -106,13 +137,13 @@ def markdown(value, lazy_load=False):
if not html: if not html:
html = escape(value) html = escape(value)
if lazy_load:
soup = BeautifulSoup(html, features="html.parser") soup = BeautifulSoup(html, features="html.parser")
for img in soup.findAll("img"): if lazy_load:
if img.get("src"): soup = _wrap_img_iframe_with_lazy_load(soup)
img["loading"] = "lazy"
for img in soup.findAll("iframe"): soup = _wrap_images_with_featherlight(soup)
if img.get("src"): soup = _open_external_links_in_new_tab(soup)
img["loading"] = "lazy"
html = str(soup) html = str(soup)
return '<div class="md-typeset content-description">%s</div>' % html return '<div class="md-typeset content-description">%s</div>' % html

View file

@ -924,3 +924,8 @@ input::placeholder{
margin-right: 0.1em; margin-right: 0.1em;
} }
} }
.featherlight-content {
max-height: 80% !important;
border-radius: 10px;
}

View file

@ -475,7 +475,11 @@ function onWindowReady() {
$('a').click(function() { $('a').click(function() {
var href = $(this).attr('href'); var href = $(this).attr('href');
if (!href || href === '#' || href.startsWith("javascript")) { var target = $(this).attr('target');
if (!href || href === '#' || href.startsWith("javascript") ||
$(this).attr("data-featherlight") ||
target === "_blank"
) {
return; return;
} }

View file

@ -297,6 +297,7 @@
{% include "extra_js.html" %} {% include "extra_js.html" %}
<script src="{{ static('common.js') }}"></script> <script src="{{ static('common.js') }}"></script>
<script src="{{ static('libs/clipboard/tooltip.js') }}"></script> <script src="{{ static('libs/clipboard/tooltip.js') }}"></script>
<script type="text/javascript" src="{{ static('libs/featherlight/featherlight.min.js') }}"></script>
<script> <script>
moment.locale('{{ LANGUAGE_CODE }}'); moment.locale('{{ LANGUAGE_CODE }}');
$(function () { $(function () {

View file

@ -1,4 +1,3 @@
<script src="{{ static('libs/featherlight/featherlight.min.js') }}" type="text/javascript"></script>
{% compress js %} {% compress js %}
{{ comment_form.media.js }} {{ comment_form.media.js }}
<script type="text/javascript"> <script type="text/javascript">

View file

@ -32,7 +32,6 @@
{% endblock %} {% endblock %}
{% block three_col_js %} {% block three_col_js %}
<script src="{{ static('libs/featherlight/featherlight.min.js') }}" type="text/javascript"></script>
<script type="text/javascript"> <script type="text/javascript">
function changeTabParameter(newTab) { function changeTabParameter(newTab) {
const url = new URL(window.location); const url = new URL(window.location);

View file

@ -42,7 +42,6 @@
} }
.featherlight-content { .featherlight-content {
border-radius: 10px;
height: 80%; height: 80%;
width: 60%; width: 60%;
overflow: auto; overflow: auto;

View file

@ -6,7 +6,6 @@
window.big_input = (window.valid_files.length > 100); window.big_input = (window.valid_files.length > 100);
</script> </script>
<script type="text/javascript" src="{{ static('jquery-ui.min.js') }}"></script> <script type="text/javascript" src="{{ static('jquery-ui.min.js') }}"></script>
<script type="text/javascript" src="{{ static('libs/featherlight/featherlight.min.js') }}"></script>
<script type="text/javascript" src="{{ static('fine-uploader/jquery.fine-uploader.js') }}"></script> <script type="text/javascript" src="{{ static('fine-uploader/jquery.fine-uploader.js') }}"></script>
<script type="text/javascript"> <script type="text/javascript">
$(function () { $(function () {

View file

@ -12,7 +12,6 @@
}); });
}); });
</script> </script>
<script type="text/javascript" src="{{ static('libs/featherlight/featherlight.min.js') }}"></script>
<script type="text/javascript"> <script type="text/javascript">
</script> </script>
{% endblock %} {% endblock %}

View file

@ -5,7 +5,6 @@
{% block js_media %} {% block js_media %}
{{ form.media.js }} {{ form.media.js }}
<script src="{{ static('libs/featherlight/featherlight.min.js') }}" type="text/javascript"></script>
<script type="text/javascript" src="{{ static('event.js') }}"></script> <script type="text/javascript" src="{{ static('event.js') }}"></script>
<script type="text/javascript"> <script type="text/javascript">
$(function () { $(function () {

View file

@ -1,5 +1,4 @@
{% compress js %} {% compress js %}
<script src="{{ static('libs/featherlight/featherlight.min.js') }}" type="text/javascript"></script>
<script type="text/javascript" src="{{ static('libs/timezone-map/timezone-picker.js') }}"></script> <script type="text/javascript" src="{{ static('libs/timezone-map/timezone-picker.js') }}"></script>
<script type="text/javascript"> <script type="text/javascript">
$(function () { $(function () {