diff --git a/dmoj/settings.py b/dmoj/settings.py index d41ff8a..e379e3e 100644 --- a/dmoj/settings.py +++ b/dmoj/settings.py @@ -33,6 +33,7 @@ SITE_ID = 1 SITE_NAME = "LQDOJ" SITE_LONG_NAME = "LQDOJ: Le Quy Don Online Judge" SITE_ADMIN_EMAIL = False +SITE_DOMAIN = "lqdoj.edu.vn" DMOJ_REQUIRE_STAFF_2FA = True diff --git a/judge/markdown.py b/judge/markdown.py index f5295ed..80eb21a 100644 --- a/judge/markdown.py +++ b/judge/markdown.py @@ -3,6 +3,8 @@ import bleach from django.utils.html import escape from bs4 import BeautifulSoup from pymdownx import superfences +from django.conf import settings +from urllib.parse import urlparse 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): extensions = EXTENSIONS html = _markdown.markdown( @@ -106,13 +137,13 @@ def markdown(value, lazy_load=False): if not html: html = escape(value) + + soup = BeautifulSoup(html, features="html.parser") if lazy_load: - soup = BeautifulSoup(html, features="html.parser") - 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" - html = str(soup) + soup = _wrap_img_iframe_with_lazy_load(soup) + + soup = _wrap_images_with_featherlight(soup) + soup = _open_external_links_in_new_tab(soup) + html = str(soup) + return '