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);
}
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<ComputedStyle> 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,