From 16d511c16f48aab4da06428549055e623d7dd5d8 Mon Sep 17 00:00:00 2001 From: Alec Ames Date: Wed, 11 Feb 2026 16:58:26 -0500 Subject: [PATCH] (feat) add multimedia embed --- src/lib/MarkdownViewer.svelte | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/src/lib/MarkdownViewer.svelte b/src/lib/MarkdownViewer.svelte index 8d04fec..34fad02 100644 --- a/src/lib/MarkdownViewer.svelte +++ b/src/lib/MarkdownViewer.svelte @@ -164,11 +164,37 @@ // resolve relative image paths for (const img of doc.querySelectorAll('img')) { const src = img.getAttribute('src'); + let finalSrc = src; if (src && !src.startsWith('http') && !src.startsWith('data:')) { - img.setAttribute('src', convertFileSrc(resolvePath(filePath, src))); - } else if (src && isYoutubeLink(src)) { - const videoId = getYoutubeId(src); - if (videoId) replaceWithYoutubeEmbed(img, videoId); + finalSrc = convertFileSrc(resolvePath(filePath, src)); + img.setAttribute('src', finalSrc); + } + + if (src) { + const ext = src.split('.').pop()?.toLowerCase(); + const isVideo = ['mp4', 'webm', 'ogg', 'mov'].includes(ext || ''); + const isAudio = ['mp3', 'wav', 'aac', 'flac', 'm4a'].includes(ext || ''); + + if (isVideo || isAudio) { + const media = doc.createElement(isVideo ? 'video' : 'audio'); + media.setAttribute('controls', ''); + media.setAttribute('src', finalSrc || ''); + media.style.maxWidth = '100%'; + + // Copy attributes + if (img.hasAttribute('width')) media.setAttribute('width', img.getAttribute('width')!); + if (img.hasAttribute('height')) media.setAttribute('height', img.getAttribute('height')!); + if (img.hasAttribute('alt')) media.setAttribute('aria-label', img.getAttribute('alt')!); + if (img.hasAttribute('title')) media.setAttribute('title', img.getAttribute('title')!); + + img.replaceWith(media); + continue; + } + + if (isYoutubeLink(src)) { + const videoId = getYoutubeId(src); + if (videoId) replaceWithYoutubeEmbed(img, videoId); + } } }