Bug 1415013: Clear servo data from the flattened tree in DestroyFramesForAndRestyle. r?bz
Otherwise we may end up leaving style Servo data on nodes that no longer are on
the flattened tree, and thus incorrectly processing (or trying to process)
restyles in them.
Also devirtualize the function while at it.
MozReview-Commit-ID: 19c1bWhzGVF
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -2927,17 +2927,17 @@ PresShell::CancelAllPendingReflows()
GetPresContext()->RefreshDriver()->RemoveLayoutFlushObserver(this);
mObservingLayoutFlushes = false;
}
ASSERT_REFLOW_SCHEDULED_STATE();
}
void
-PresShell::DestroyFramesForAndRestyle(Element* aElement)
+nsIPresShell::DestroyFramesForAndRestyle(Element* aElement)
{
MOZ_ASSERT(aElement);
NS_ENSURE_TRUE_VOID(mPresContext);
if (!mDidInitialize) {
return;
}
nsAutoScriptBlocker scriptBlocker;
@@ -2945,16 +2945,20 @@ PresShell::DestroyFramesForAndRestyle(El
// Mark ourselves as not safe to flush while we're doing frame destruction.
++mChangeNestCount;
nsCSSFrameConstructor* fc = FrameConstructor();
fc->BeginUpdate();
bool didReconstruct = fc->DestroyFramesFor(aElement);
fc->EndUpdate();
+ if (aElement->IsStyledByServo()) {
+ ServoRestyleManager::ClearServoDataFromSubtree(aElement);
+ }
+
auto changeHint = didReconstruct
? nsChangeHint(0)
: nsChangeHint_ReconstructFrame;
// NOTE(emilio): eRestyle_Subtree is needed to force also a full subtree
// restyle for the content (in Stylo, where the existence of frames != the
// existence of styles).
mPresContext->RestyleManager()->PostRestyleEvent(
--- a/layout/base/PresShell.h
+++ b/layout/base/PresShell.h
@@ -125,17 +125,16 @@ public:
virtual void FrameNeedsReflow(nsIFrame *aFrame, IntrinsicDirty aIntrinsicDirty,
nsFrameState aBitToAdd,
ReflowRootHandling aRootHandling =
eInferFromBitToAdd) override;
virtual void FrameNeedsToContinueReflow(nsIFrame *aFrame) override;
virtual void CancelAllPendingReflows() override;
virtual void DoFlushPendingNotifications(mozilla::FlushType aType) override;
virtual void DoFlushPendingNotifications(mozilla::ChangesToFlush aType) override;
- virtual void DestroyFramesForAndRestyle(mozilla::dom::Element* aElement) override;
/**
* Post a callback that should be handled after reflow has finished.
*/
virtual nsresult PostReflowCallback(nsIReflowCallback* aCallback) override;
virtual void CancelReflowCallback(nsIReflowCallback* aCallback) override;
virtual void ClearFrameRefs(nsIFrame* aFrame) override;
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -524,17 +524,17 @@ public:
virtual void NotifyCounterStylesAreDirty() = 0;
/**
* Destroy the frames for aElement, and reconstruct them asynchronously if
* needed.
*
* Note that this may destroy frames for an ancestor instead.
*/
- virtual void DestroyFramesForAndRestyle(mozilla::dom::Element* aElement) = 0;
+ void DestroyFramesForAndRestyle(mozilla::dom::Element* aElement);
void PostRecreateFramesFor(mozilla::dom::Element* aElement);
void RestyleForAnimation(mozilla::dom::Element* aElement,
nsRestyleHint aHint);
// ShadowRoot has APIs that can change styles so we only
// want to restyle elements in the ShadowRoot and not the whole
// document.