Bug 1675950 - Check for explicit restyles posted to pseudo-elements to check whether we need a style flush in getComputedStyle. r=heycam

Font loading invalidation may invalidate only pseudo-elements, like it
happens on this test-case.

Once we get to testing first-line / first-letter in the test-case
(css/css-values/ch-pseudo-recalc-on-font-load.html), we end up flushing
because those end up posting the restyle to the parent element
correctly.

Differential Revision: https://phabricator.services.mozilla.com/D96373
This commit is contained in:
Emilio Cobos Álvarez 2020-11-09 11:59:31 +00:00
Родитель e86e7489c7
Коммит 15074fcfdf
1 изменённых файлов: 23 добавлений и 18 удалений

Просмотреть файл

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