Bug 1389790: Ensure we always have an up-to-date style context even if we have no frame. r?heycam
I'm still not quite sure how may we end up restyling a text node under there,
but all my attempts to build a test-case have failed.
Anyway this is the right thing to do.
MozReview-Commit-ID: FitqSKhNt2n
--- a/layout/base/ServoRestyleManager.cpp
+++ b/layout/base/ServoRestyleManager.cpp
@@ -786,44 +786,48 @@ ServoRestyleManager::ProcessPostTraversa
thisFrameRestyleState.emplace(*styleFrame, aRestyleState, changeHint, type);
}
// We can't really assume as used changes from display: contents elements (or
// other elements without frames).
ServoRestyleState& childrenRestyleState =
thisFrameRestyleState ? *thisFrameRestyleState : aRestyleState;
- RefPtr<ServoStyleContext> newContext = nullptr;
+ RefPtr<ServoStyleContext> upToDateContext =
+ (wasRestyled || !oldStyleContext)
+ ? aRestyleState.StyleSet().ResolveServoStyle(aElement)
+ : oldStyleContext;
+
+ MOZ_ASSERT(upToDateContext);
+
if (wasRestyled && oldStyleContext) {
MOZ_ASSERT(styleFrame || displayContentsStyle);
- newContext =
- aRestyleState.StyleSet().ResolveServoStyle(aElement);
- MOZ_ASSERT(oldStyleContext->ComputedData() != newContext->ComputedData());
+ MOZ_ASSERT(oldStyleContext->ComputedData() != upToDateContext->ComputedData());
- newContext->ResolveSameStructsAs(oldStyleContext);
+ upToDateContext->ResolveSameStructsAs(oldStyleContext);
// We want to walk all the continuations here, even the ones with different
// styles. In practice, the only reason we get continuations with different
// styles here is ::first-line (::first-letter never affects element
// styles). But in that case, newContext is the right context for the
// _later_ continuations anyway (the ones not affected by ::first-line), not
// the earlier ones, so there is no point stopping right at the point when
// we'd actually be setting the right style context.
//
// This does mean that we may be setting the wrong style context on our
// initial continuations; ::first-line fixes that up after the fact.
for (nsIFrame* f = styleFrame; f; f = f->GetNextContinuation()) {
MOZ_ASSERT_IF(f != styleFrame, !f->GetAdditionalStyleContext(0));
- f->SetStyleContext(newContext);
+ f->SetStyleContext(upToDateContext);
}
if (MOZ_UNLIKELY(displayContentsStyle)) {
MOZ_ASSERT(!styleFrame);
PresContext()->FrameConstructor()->
- ChangeRegisteredDisplayContentsStyleFor(aElement, newContext);
+ ChangeRegisteredDisplayContentsStyleFor(aElement, upToDateContext);
}
if (styleFrame) {
UpdateAdditionalStyleContexts(styleFrame, aRestyleState);
styleFrame->UpdateStyleOfOwnedAnonBoxes(childrenRestyleState);
}
if (!aElement->GetParent()) {
@@ -851,19 +855,16 @@ ServoRestyleManager::ProcessPostTraversa
const bool traverseElementChildren =
NeedsToTraverseElementChildren(*aElement);
const bool descendantsNeedFrames =
aElement->HasFlag(NODE_DESCENDANTS_NEED_FRAMES);
const bool traverseTextChildren = wasRestyled || descendantsNeedFrames;
bool recreatedAnyContext = wasRestyled;
if (traverseElementChildren || traverseTextChildren) {
- ServoStyleContext* upToDateContext =
- wasRestyled ? newContext : oldStyleContext;
-
StyleChildrenIterator it(aElement);
TextPostTraversalState textState(*upToDateContext,
displayContentsStyle && wasRestyled,
childrenRestyleState);
for (nsIContent* n = it.GetNextChild(); n; n = it.GetNextChild()) {
if (traverseElementChildren && n->IsElement()) {
recreatedAnyContext |= ProcessPostTraversal(n->AsElement(),
upToDateContext,