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

test

parent 9d357063
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -115,7 +115,8 @@ void libhtmlpp::collectStyleBlocks(CSSStyleSheet &sheet, Element &root)

libhtmlpp::CSSRuleResult libhtmlpp::getCSSRules(HtmlElement &target,
                                                  const CSSStyleSheet &sheet,
                                                  std::set<std::string> &seenMediaBlocks)
                                                  std::set<std::string> &seenMediaBlocks,
                                                  const std::vector<AncestorFrame> *ancestors)
{
    CSSRuleResult result;

@@ -130,6 +131,7 @@ libhtmlpp::CSSRuleResult libhtmlpp::getCSSRules(HtmlElement &target,
    std::string cssClass = target.getAtributte("class");
    std::string id = target.getAtributte("id");

    sheet.collectApproximateMatches(tag, cssClass, id, result.properties, result.mediaRules, seenMediaBlocks);
    sheet.collectApproximateMatches(tag, cssClass, id, result.properties, result.mediaRules,
                                     seenMediaBlocks, ancestors);
    return result;
}
+7 −1
Original line number Diff line number Diff line
@@ -75,7 +75,13 @@ namespace libhtmlpp {
     *  across many calls (e.g. one per element while walking a whole
     *  document) to avoid accumulating the exact same @media block's text
     *  once per matching element -- see
     *  CSSStyleSheet::collectApproximateMatches. */
     *  CSSStyleSheet::collectApproximateMatches. @p ancestors is forwarded to
     *  CSSStyleSheet::collectApproximateMatches exactly as described there:
     *  nullptr (the default) means no ancestor/combinator verification
     *  (this function's original behavior), a non-null chain (see
     *  AncestorFrame) makes a descendant selector's leading compounds
     *  required to actually be found among @p target's ancestors, in order,
     *  instead of being ignored. */
    CSSRuleResult getCSSRules(HtmlElement &target,
                               const CSSStyleSheet &sheet,
                               std::set<std::string> &seenMediaBlocks,
+49 −0
Original line number Diff line number Diff line
@@ -259,6 +259,55 @@ int main(){
        }
    }

    // --- getCSSRules with an ancestor chain: the real bug, end-to-end ---
    std::cout << "=== getCSSRules with ancestor chain ===" << std::endl;
    {
        using libhtmlpp::AncestorFrame;
        std::string html =
            "<html><head>"
            "<style>"
            ".frame { padding-top: 100px; }"
            ".header .frame { padding-top: 0; }"
            "</style>"
            "</head><body>"
            "<div class=\"header\"><div id=\"headerFrame\" class=\"frame\">hi</div></div>"
            "<div class=\"hero\"><div id=\"heroFrame\" class=\"frame\">hi</div></div>"
            "</body></html>";

        libhtmlpp::HtmlString htmlString(html);
        libhtmlpp::Element &root = htmlString.parse();

        libhtmlpp::CSSStyleSheet sheet;
        libhtmlpp::collectStyleBlocks(sheet, root);

        libhtmlpp::HtmlElement *headerFrame =
            static_cast<libhtmlpp::HtmlElement*>(&root)->getElementbyID("headerFrame");
        libhtmlpp::HtmlElement *heroFrame =
            static_cast<libhtmlpp::HtmlElement*>(&root)->getElementbyID("heroFrame");
        check(headerFrame != nullptr && heroFrame != nullptr, "found both target elements by id");

        if (headerFrame && heroFrame) {
            std::set<std::string> seen;
            auto noAncestorsResult = libhtmlpp::getCSSRules(*heroFrame, sheet, seen);
            check(noAncestorsResult.properties["padding-top"] == "0",
                  "without an ancestor chain, the header-only rule still bleeds onto an unrelated "
                  "element -- this is the pre-fix behavior, unchanged for callers that pass none");

            std::vector<AncestorFrame> headerAncestors = {{"div", {"header"}, ""}};
            std::set<std::string> seen2;
            auto headerResult = libhtmlpp::getCSSRules(*headerFrame, sheet, seen2, &headerAncestors);
            check(headerResult.properties["padding-top"] == "0",
                  "with its real ancestor chain, the header's own frame still gets the header-only rule");

            std::vector<AncestorFrame> heroAncestors = {{"div", {"hero"}, ""}};
            std::set<std::string> seen3;
            auto heroResult = libhtmlpp::getCSSRules(*heroFrame, sheet, seen3, &heroAncestors);
            check(heroResult.properties["padding-top"] == "100px",
                  "with its real (non-header) ancestor chain, the hero's frame keeps the general "
                  "rule instead of the header-only one -- the actual bug fix");
        }
    }

    // --- resolveCSSVariables ---
    std::cout << "=== resolveCSSVariables ===" << std::endl;
    {