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 <img src="images/wensday%201%20full%202.png"> ```` 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!
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user