From b5e53c97e6788866437a023d78d945bb92c5af6d Mon Sep 17 00:00:00 2001 From: LaurensBartelds Date: Tue, 21 Apr 2026 21:37:27 +0200 Subject: [PATCH] feat: add QuestionMedia with DOMPurify SVG sanitization --- frontend/src/components/QuestionMedia.tsx | 53 +++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 frontend/src/components/QuestionMedia.tsx diff --git a/frontend/src/components/QuestionMedia.tsx b/frontend/src/components/QuestionMedia.tsx new file mode 100644 index 0000000..7d7693b --- /dev/null +++ b/frontend/src/components/QuestionMedia.tsx @@ -0,0 +1,53 @@ +import DOMPurify from 'dompurify' +import { highlightCode } from '../utils/latex' +import type { Question } from '../types' + +interface Props { + q: Question +} + +export default function QuestionMedia({ q }: Props) { + return ( + <> + {q.image && ( +
+ {q.image.alt + {q.image.caption && ( +
{q.image.caption}
+ )} +
+ )} + {q.audio && ( +
+ +
+ )} + {q.code && ( + // highlightCode runs escapeHtml on the source first — output is safe +
+      )}
+      {q.table && (
+        
+          
+            {q.table.headers.map((h, i) => )}
+          
+          
+            {q.table.rows.map((row, i) => (
+              {row.map((cell, j) => )}
+            ))}
+          
+        
{h}
{cell}
+ )} + {q.svg && ( + // SVG is user-provided — sanitize with DOMPurify before rendering +
+ )} + + ) +}