diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp index 27d31b1c8641..89031e9d2dc5 100644 --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -83,6 +83,22 @@ static nsDOMCSSValueList* GetROCSSValueList(bool aCommaDelimited) { return new nsDOMCSSValueList(aCommaDelimited); } +static Element* GetRenderedElement(Element* aElement, nsAtom* aPseudo) { + if (aPseudo == nsCSSPseudoElements::before()) { + return nsLayoutUtils::GetBeforePseudo(aElement); + } + if (aPseudo == nsCSSPseudoElements::after()) { + return nsLayoutUtils::GetAfterPseudo(aElement); + } + if (aPseudo == nsCSSPseudoElements::marker()) { + return nsLayoutUtils::GetMarkerPseudo(aElement); + } + if (!aPseudo) { + return aElement; + } + return nullptr; +} + // Whether aDocument needs to restyle for aElement static bool ElementNeedsRestyle(Element* aElement, nsAtom* aPseudo, bool aMayNeedToFlushLayout) { @@ -151,12 +167,12 @@ static bool ElementNeedsRestyle(Element* aElement, nsAtom* aPseudo, return false; } - // Then if there is a restyle root, we check if the root is an ancestor of - // this content. If it is not, then we don't need to restyle immediately. - // Note this is different from Gecko: we only check if any ancestor needs - // to restyle _itself_, not descendants, since dirty descendants can be - // another subtree. - return Servo_HasPendingRestyleAncestor(aElement, aMayNeedToFlushLayout); + // If there's a pseudo, we need to prefer that element, as the pseudo itself + // may have explicit restyles. + Element* styledElement = GetRenderedElement(aElement, aPseudo); + // Try to skip the restyle otherwise. + return Servo_HasPendingRestyleAncestor( + styledElement ? styledElement : aElement, aMayNeedToFlushLayout); } /** @@ -516,18 +532,7 @@ already_AddRefed nsComputedDOMStyle::DoGetComputedStyleNoFlush( // mPrimaryFrame). Remove it once that's fixed. if (inDocWithShell && aStyleType == eAll && !aElement->IsHTMLElement(nsGkAtoms::area)) { - Element* element = nullptr; - if (aPseudo == nsCSSPseudoElements::before()) { - element = nsLayoutUtils::GetBeforePseudo(aElement); - } else if (aPseudo == nsCSSPseudoElements::after()) { - element = nsLayoutUtils::GetAfterPseudo(aElement); - } else if (aPseudo == nsCSSPseudoElements::marker()) { - element = nsLayoutUtils::GetMarkerPseudo(aElement); - } else if (!aPseudo) { - element = aElement; - } - - if (element) { + if (Element* element = GetRenderedElement(aElement, aPseudo)) { if (nsIFrame* styleFrame = nsLayoutUtils::GetStyleFrame(element)) { ComputedStyle* result = styleFrame->Style(); // Don't use the style if it was influenced by pseudo-elements,