Loading editor/src/htmlimport.cpp +60 −2 Changes for editor/src/htmlimport.cpp: 60 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -1206,6 +1206,53 @@ std::string resolveSrcset(const std::string &baseUrl, const std::string &srcset) return out; } // Picks the single highest-resolution candidate from a srcset-syntax list // ("<url> [descriptor], ..."), comparing width ("480w") or pixel-density // ("2x") descriptors numerically -- used as a fallback source for widgets // (like Image) that only ever have room for one src, never a full srcset. // Falls back to the last candidate when none of them have a (parseable) // descriptor, since such lists conventionally order small-to-large. std::string pickLargestSrcsetCandidate(const std::string &srcset) { std::string best, fallbackLast; double bestScore = -1; bool haveAnyScore = false; size_t start = 0; while (start <= srcset.size()) { size_t comma = srcset.find(',', start); std::string candidate = srcset.substr(start, comma == std::string::npos ? std::string::npos : comma - start); size_t s = candidate.find_first_not_of(" \t\r\n"); size_t e = candidate.find_last_not_of(" \t\r\n"); if (s != std::string::npos) { candidate = candidate.substr(s, e - s + 1); size_t ws = candidate.find_first_of(" \t\r\n"); std::string url = (ws == std::string::npos) ? candidate : candidate.substr(0, ws); std::string descriptor = (ws == std::string::npos) ? "" : candidate.substr(ws + 1); if (!url.empty()) fallbackLast = url; if (!descriptor.empty()) { try { size_t idx = 0; double score = std::stod(descriptor, &idx); if (idx > 0 && (!haveAnyScore || score > bestScore)) { bestScore = score; best = url; haveAnyScore = true; } } catch (...) {} } } if (comma == std::string::npos) break; start = comma + 1; } return haveAnyScore ? best : fallbackLast; } // Many real-world pages lazy-load images (lazysizes.js and similar // libraries all use this same convention): the real image lives in // data-src/data-srcset, while src/srcset hold a tiny placeholder (a blurred Loading @@ -1229,9 +1276,19 @@ void preferLazyImageSrc(libhtmlpp::Element *node) if (tag == "img" || tag == "source") { std::string dataSrc = hel->getAtributte("data-src"); if (!dataSrc.empty()) hel->setAttribute("src", dataSrc); std::string dataSrcset = hel->getAtributte("data-srcset"); if (!dataSrc.empty()) { hel->setAttribute("src", dataSrc); } else if (!dataSrcset.empty()) { // No plain data-src (common with lazysizes-style markup // that only sets data-srcset) -- Image widgets only ever // keep a single src, never a srcset, so pick the best // candidate rather than keep the low-res src placeholder. std::string best = pickLargestSrcsetCandidate(dataSrcset); if (!best.empty()) hel->setAttribute("src", best); } if (!dataSrcset.empty()) hel->setAttribute("srcset", dataSrcset); } Loading Loading @@ -1485,6 +1542,7 @@ bool blogi::htmlimport::convertHtmlToWidgetXml(const std::string &html, try { page.loadString(index, html); root = &index; preferLazyImageSrc(root); if (!baseUrl.empty()) rewriteRelativeUrls(root, baseUrl); } catch (...) { // Fallback: single CustomHtml widget with raw HTML Loading Loading
editor/src/htmlimport.cpp +60 −2 Changes for editor/src/htmlimport.cpp: 60 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -1206,6 +1206,53 @@ std::string resolveSrcset(const std::string &baseUrl, const std::string &srcset) return out; } // Picks the single highest-resolution candidate from a srcset-syntax list // ("<url> [descriptor], ..."), comparing width ("480w") or pixel-density // ("2x") descriptors numerically -- used as a fallback source for widgets // (like Image) that only ever have room for one src, never a full srcset. // Falls back to the last candidate when none of them have a (parseable) // descriptor, since such lists conventionally order small-to-large. std::string pickLargestSrcsetCandidate(const std::string &srcset) { std::string best, fallbackLast; double bestScore = -1; bool haveAnyScore = false; size_t start = 0; while (start <= srcset.size()) { size_t comma = srcset.find(',', start); std::string candidate = srcset.substr(start, comma == std::string::npos ? std::string::npos : comma - start); size_t s = candidate.find_first_not_of(" \t\r\n"); size_t e = candidate.find_last_not_of(" \t\r\n"); if (s != std::string::npos) { candidate = candidate.substr(s, e - s + 1); size_t ws = candidate.find_first_of(" \t\r\n"); std::string url = (ws == std::string::npos) ? candidate : candidate.substr(0, ws); std::string descriptor = (ws == std::string::npos) ? "" : candidate.substr(ws + 1); if (!url.empty()) fallbackLast = url; if (!descriptor.empty()) { try { size_t idx = 0; double score = std::stod(descriptor, &idx); if (idx > 0 && (!haveAnyScore || score > bestScore)) { bestScore = score; best = url; haveAnyScore = true; } } catch (...) {} } } if (comma == std::string::npos) break; start = comma + 1; } return haveAnyScore ? best : fallbackLast; } // Many real-world pages lazy-load images (lazysizes.js and similar // libraries all use this same convention): the real image lives in // data-src/data-srcset, while src/srcset hold a tiny placeholder (a blurred Loading @@ -1229,9 +1276,19 @@ void preferLazyImageSrc(libhtmlpp::Element *node) if (tag == "img" || tag == "source") { std::string dataSrc = hel->getAtributte("data-src"); if (!dataSrc.empty()) hel->setAttribute("src", dataSrc); std::string dataSrcset = hel->getAtributte("data-srcset"); if (!dataSrc.empty()) { hel->setAttribute("src", dataSrc); } else if (!dataSrcset.empty()) { // No plain data-src (common with lazysizes-style markup // that only sets data-srcset) -- Image widgets only ever // keep a single src, never a srcset, so pick the best // candidate rather than keep the low-res src placeholder. std::string best = pickLargestSrcsetCandidate(dataSrcset); if (!best.empty()) hel->setAttribute("src", best); } if (!dataSrcset.empty()) hel->setAttribute("srcset", dataSrcset); } Loading Loading @@ -1485,6 +1542,7 @@ bool blogi::htmlimport::convertHtmlToWidgetXml(const std::string &html, try { page.loadString(index, html); root = &index; preferLazyImageSrc(root); if (!baseUrl.empty()) rewriteRelativeUrls(root, baseUrl); } catch (...) { // Fallback: single CustomHtml widget with raw HTML Loading