From 90d4c885e112df9079b425fc0987339eeffcd93d Mon Sep 17 00:00:00 2001 From: Blue Date: Sat, 16 May 2026 04:30:49 +0200 Subject: [PATCH] fix: update URL-encoded image during EPUB optimization (#1985) ## Summary * **What is the goal of this PR?** Fix EPUB optimization when XHTML image references are URL-encoded. * **What changes are included?** The optimizer already converts image files to `.jpg`, but XHTML files could still reference the original URL-encoded image path, for example: ```html ```` The optimized EPUB then contained the converted file: ```text images/wensday 1 full 2.jpg ``` but the XHTML still pointed to the old `.png`, so CrossPoint failed to extract/render the image. The issue was that the previous replacement logic matched only the plain filename form, such as: ```text wensday 1 full 2.png ``` but not the URL-encoded form: ```text wensday%201%20full%202.png ``` This PR updates XHTML image `src` attributes through the existing DOMParser pass by decoding and resolving the image path before matching it against renamed images. After this fix, the optimized EPUB correctly rewrites the XHTML image reference to the generated `.jpg`, and the image renders correctly. --- ### AI Usage While CrossPoint doesn't have restrictions on AI tools in contributing, please be transparent about their usage as it helps set the right context for reviewers. Did you use AI tools to help write this code? _**PARTIALLY**_ --- Please let me know if you have questions, Thank you! --- src/network/html/FilesPage.html | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/network/html/FilesPage.html b/src/network/html/FilesPage.html index 8c8880ac..eb21ae37 100644 --- a/src/network/html/FilesPage.html +++ b/src/network/html/FilesPage.html @@ -4316,10 +4316,6 @@ async function convertEpubFile(file, progressCallback) { const r2 = fixSvgWrappedImages(t); if (r2.fixed) { t = r2.c; logFix(`SVG images (${r2.count})`, xhtmlPath.split('/').pop()); } - for (const [o, n] of Object.entries(renamed)) { - t = t.split(o.split('/').pop()).join(n.split('/').pop()); - } - // Use DOMParser for all img modifications: remove width/height and handle split images try { const parser = new DOMParser(); @@ -4335,6 +4331,20 @@ async function convertEpubFile(file, progressCallback) { for (const img of allImgElements) { if (img.hasAttribute('width')) { img.removeAttribute('width'); modified = true; } if (img.hasAttribute('height')) { img.removeAttribute('height'); modified = true; } + + const src = img.getAttribute('src'); + if (src) { + const decodedSrc = decodeHref(src); + const resolvedSrc = resolvePath(xhtmlPath, decodedSrc); + + const match = Object.entries(renamed).find(([oldPath]) => resolvedSrc === oldPath); + + if (match) { + const [oldPath, newPath] = match; + img.setAttribute('src', decodedSrc.replace(oldPath.split('/').pop(), newPath.split('/').pop())); + modified = true; + } + } } // Handle split images with path collision prevention