Commit cd90a6d4 authored by jan.koester's avatar jan.koester
Browse files

test

parent b8e950b6
Loading
Loading
Loading
Loading
+60 −2
Changes for editor/src/htmlimport.cpp: 60 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -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
@@ -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);
            }

@@ -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