From 2fed1cc6e71bd705ea2a5bbd617fdc9ea6e4de02 Mon Sep 17 00:00:00 2001 From: Gigi Date: Mon, 20 Oct 2025 21:11:58 +0200 Subject: [PATCH] fix: robustly replace img tags with video URLs - Changed approach to find ALL img tags first, then check if they contain video URLs - Properly escapes regex special characters in img tags before replacement - Fixes issue where img tags with video src attributes were not being replaced - Handles edge cases like React-added attributes (node=[object Object]) - Now correctly converts markdown video images to embedded players --- src/components/VideoEmbedProcessor.tsx | 27 ++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/components/VideoEmbedProcessor.tsx b/src/components/VideoEmbedProcessor.tsx index 7236d848..de9ef449 100644 --- a/src/components/VideoEmbedProcessor.tsx +++ b/src/components/VideoEmbedProcessor.tsx @@ -29,17 +29,24 @@ const VideoEmbedProcessor = forwardRef // Find all video URLs in img tags and replace the entire tag let result = html - // Pattern to match img tags with video URLs in src attribute - const imgVideoPattern = /]+src=["']?(https?:\/\/[^\s<>"']+\.(mp4|webm|ogg|mov|avi|mkv|m4v)[^\s<>"']*)["']?[^>]*>/gi - const imgMatches = result.match(imgVideoPattern) || [] + // Find all src attributes with video URLs inside img tags + const imgTagPattern = /]*>/gi + const allImgTags = result.match(imgTagPattern) || [] const imgVideoUrls: string[] = [] - imgMatches.forEach((imgTag, index) => { + let placeholderIndex = 0 + + allImgTags.forEach((imgTag) => { + // Extract src attribute value const srcMatch = imgTag.match(/src=["']?(https?:\/\/[^\s<>"']+\.(mp4|webm|ogg|mov|avi|mkv|m4v)[^\s<>"']*)["']?/i) if (srcMatch && srcMatch[1]) { - imgVideoUrls.push(srcMatch[1]) - const placeholder = `__VIDEO_EMBED_${index}__` - result = result.replace(imgTag, placeholder) + const videoUrl = srcMatch[1] + imgVideoUrls.push(videoUrl) + const placeholder = `__VIDEO_EMBED_${placeholderIndex}__` + // Escape special regex characters in the img tag to ensure proper replacement + const escapedTag = imgTag.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + result = result.replace(new RegExp(escapedTag, ''), placeholder) + placeholderIndex++ } }) @@ -82,9 +89,9 @@ const VideoEmbedProcessor = forwardRef const result: string[] = [] // Extract video URLs from img tags - const imgVideoPattern = /]+src=["']?(https?:\/\/[^\s<>"']+\.(mp4|webm|ogg|mov|avi|mkv|m4v)[^\s<>"']*)["']?[^>]*>/gi - const imgMatches = html.match(imgVideoPattern) || [] - imgMatches.forEach((imgTag) => { + const imgTagPattern = /]*>/gi + const allImgTags = html.match(imgTagPattern) || [] + allImgTags.forEach((imgTag) => { const srcMatch = imgTag.match(/src=["']?(https?:\/\/[^\s<>"']+\.(mp4|webm|ogg|mov|avi|mkv|m4v)[^\s<>"']*)["']?/i) if (srcMatch && srcMatch[1]) { result.push(srcMatch[1])