From 449413b96d2539297713cd4c1764e6d7bd13fdb3 Mon Sep 17 00:00:00 2001 From: bender Date: Sat, 21 Feb 2026 00:16:44 +0000 Subject: [PATCH 1/5] Update src/app/blog/page.tsx --- src/app/blog/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/blog/page.tsx b/src/app/blog/page.tsx index 96cc053..cc386c1 100644 --- a/src/app/blog/page.tsx +++ b/src/app/blog/page.tsx @@ -14,7 +14,7 @@ export default function BlogPage() { Date: Sat, 21 Feb 2026 00:16:45 +0000 Subject: [PATCH 2/5] Update src/app/layout.tsx --- src/app/layout.tsx | 102 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 94 insertions(+), 8 deletions(-) diff --git a/src/app/layout.tsx b/src/app/layout.tsx index aabf17e..0c9a078 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -90,7 +90,9 @@ export default function RootLayout({ ' background-color: #4d96ff05 !important;' + '}' + 'img.webild-hover,' + - 'img.webild-selected {' + + 'img.webild-selected,' + + 'video.webild-hover,' + + 'video.webild-selected {' + ' outline-offset: 2px !important;' + '}' + '.webild-element-type-label {' + @@ -162,6 +164,10 @@ export default function RootLayout({ return 'Image'; } + if (tagName === 'video') { + return 'Video'; + } + const backgroundImage = computedStyle.backgroundImage; if (backgroundImage && backgroundImage !== 'none') { const urlMatch = backgroundImage.match(/url(['"]?([^'")]+)['"]?)/); @@ -244,6 +250,38 @@ export default function RootLayout({ return url; }; + const getMediaTypeFromUrl = (url) => { + const videoExts = ['.mp4', '.webm', '.ogg', '.mov', '.avi', '.mkv', '.m4v', '.wmv']; + const imageExts = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg', '.bmp', '.ico', '.tiff', '.avif']; + try { + const pathname = new URL(url).pathname.toLowerCase(); + if (videoExts.some(function(ext) { return pathname.endsWith(ext); })) return 'video'; + if (imageExts.some(function(ext) { return pathname.endsWith(ext); })) return 'image'; + } catch(e) {} + return 'unknown'; + }; + + const swapMediaElement = (oldEl, newTag, newSrc) => { + const newEl = document.createElement(newTag); + Array.from(oldEl.attributes).forEach(function(attr) { + if (attr.name !== 'src' && attr.name !== 'alt' && attr.name !== 'srcset' && attr.name !== 'autoplay' && attr.name !== 'loop' && attr.name !== 'muted' && attr.name !== 'playsinline') { + try { newEl.setAttribute(attr.name, attr.value); } catch(e) {} + } + }); + newEl.style.cssText = oldEl.style.cssText; + if (newTag === 'video') { + newEl.setAttribute('autoplay', ''); + newEl.setAttribute('loop', ''); + newEl.setAttribute('muted', ''); + newEl.setAttribute('playsinline', ''); + } + newEl.src = newSrc; + if (oldEl.parentNode) { + oldEl.parentNode.replaceChild(newEl, oldEl); + } + return newEl; + }; + const getElementInfo = (element, assignId = false) => { const rect = element.getBoundingClientRect(); const tagName = element.tagName.toLowerCase(); @@ -286,7 +324,18 @@ export default function RootLayout({ isBackground: false }; } - + + if (tagName === 'video') { + const rawSrc = element.src || element.currentSrc || (element.querySelector('source') && element.querySelector('source').src) || ''; + const resolvedSrc = extractOriginalUrl(rawSrc); + info.imageData = { + src: resolvedSrc, + alt: element.getAttribute('aria-label') || undefined, + isBackground: false, + isVideo: true + }; + } + const computedStyle = window.getComputedStyle(element); const backgroundImage = computedStyle.backgroundImage; if (backgroundImage && backgroundImage !== 'none') { @@ -334,7 +383,8 @@ export default function RootLayout({ const tagName = element.tagName?.toLowerCase(); if (invalidElements.includes(tagName)) return false; const isImage = tagName === 'img'; - if (isImage) return true; + const isVideo = tagName === 'video'; + if (isImage || isVideo) return true; const hasInnerHTML = element.innerHTML && element.innerHTML.trim().length > 0; const hasTextContent = element.textContent && element.textContent.trim().length > 0; const hasChildren = element.children && element.children.length > 0; @@ -374,7 +424,7 @@ export default function RootLayout({ node.nodeType === Node.TEXT_NODE && node.textContent && node.textContent.trim().length > 0 ); - const hasImages = element.tagName === 'IMG' || computedStyle.backgroundImage !== 'none' || element.querySelector('img'); + const hasImages = element.tagName === 'IMG' || element.tagName === 'VIDEO' || computedStyle.backgroundImage !== 'none' || element.querySelector('img') || element.querySelector('video'); const isInteractive = ['BUTTON', 'A', 'INPUT', 'SELECT', 'TEXTAREA'].includes(element.tagName); const hasFewChildren = element.children.length <= 3; const area = rect.width * rect.height; @@ -1055,11 +1105,22 @@ export default function RootLayout({ updateButtonText(element, change.oldValue); } } else if (change.type === 'replaceImage') { - const isBackground = element.tagName.toLowerCase() !== 'img'; + const revertTag = element.tagName.toLowerCase(); + const isBackground = revertTag !== 'img' && revertTag !== 'video'; if (isBackground) { element.style.backgroundImage = change.oldValue ? 'url(' + change.oldValue + ')' : ''; } else { - element.src = change.oldValue; + const oldMediaType = getMediaTypeFromUrl(change.oldValue); + if (revertTag === 'video' && oldMediaType === 'image') { + swapMediaElement(element, 'img', change.oldValue); + } else if (revertTag === 'img' && oldMediaType === 'video') { + swapMediaElement(element, 'video', change.oldValue); + } else if (revertTag === 'video') { + element.src = change.oldValue; + element.load(); + } else { + element.src = change.oldValue; + } } } } catch (err) { @@ -1159,7 +1220,7 @@ export default function RootLayout({ if (!isActive) return; if (e.data.type === 'webild-replace-image') { - const { selector, newSrc, isBackground } = e.data.data; + const { selector, newSrc, isBackground, allowMediaTypeSwap } = e.data.data; let element = null; try { @@ -1190,7 +1251,32 @@ export default function RootLayout({ replaced = true; } else if (element.tagName.toLowerCase() === 'img') { oldValue = element.src; - element.src = newSrc; + const newMediaType = getMediaTypeFromUrl(newSrc); + if (newMediaType === 'video' && allowMediaTypeSwap) { + const swapped = swapMediaElement(element, 'video', newSrc); + if (selectedElement === element) selectedElement = swapped; + element = swapped; + } else { + element.src = newSrc; + } + replaced = true; + } else if (element.tagName.toLowerCase() === 'video') { + oldValue = element.src || element.currentSrc || ''; + const newMediaType = getMediaTypeFromUrl(newSrc); + const sources = element.querySelectorAll('source'); + if (newMediaType === 'image' && allowMediaTypeSwap) { + const swapped = swapMediaElement(element, 'img', newSrc); + if (selectedElement === element) selectedElement = swapped; + element = swapped; + } else { + if (sources.length > 0) { + sources.forEach(function(source) { source.src = newSrc; }); + element.load(); + } else { + element.src = newSrc; + element.load(); + } + } replaced = true; } else { const hasBackgroundImage = window.getComputedStyle(element).backgroundImage !== 'none'; -- 2.49.1 From d647d292ff7af75ff7076c2c56f29b2b199edafe Mon Sep 17 00:00:00 2001 From: bender Date: Sat, 21 Feb 2026 00:16:46 +0000 Subject: [PATCH 3/5] Update src/app/page.tsx --- src/app/page.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/page.tsx b/src/app/page.tsx index 6457e78..a14e289 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -17,7 +17,7 @@ export default function LandingPage() { Date: Sat, 21 Feb 2026 00:16:47 +0000 Subject: [PATCH 4/5] Update src/app/shop/[id]/page.tsx --- src/app/shop/[id]/page.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/shop/[id]/page.tsx b/src/app/shop/[id]/page.tsx index 776d4c0..83d64f8 100644 --- a/src/app/shop/[id]/page.tsx +++ b/src/app/shop/[id]/page.tsx @@ -71,7 +71,7 @@ export default function ProductPage({ params }: ProductPageProps) { Date: Sat, 21 Feb 2026 00:16:48 +0000 Subject: [PATCH 5/5] Update src/app/shop/page.tsx --- src/app/shop/page.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/shop/page.tsx b/src/app/shop/page.tsx index f3c9345..b5b6d7a 100644 --- a/src/app/shop/page.tsx +++ b/src/app/shop/page.tsx @@ -21,7 +21,7 @@ export default function ShopPage() {