From a9f670204453e6a17dd33a290541755f5978fd46 Mon Sep 17 00:00:00 2001 From: Gerald Squelart Date: Tue, 10 Jul 2018 15:35:48 +1000 Subject: [PATCH] Bug 1459937 - In DEBUG mode, verify that reparenting direction is correct - r=dbaron MozReview-Commit-ID: JPfg9YtBm6M --HG-- extra : rebase_source : f56a9a4a666fc61e69ba537a69e3161b58083d02 --- layout/generic/nsBlockFrame.cpp | 34 +++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index b7bfb04d573e..e468379daced 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -623,9 +623,27 @@ ReparentFrameInternal(nsIFrame* aFrame, nsContainerFrame* aOldParent, } static bool -ShouldMarkReparentedFramesDirty(nsIFrame* aNewParent, - ReparentingDirection aDirection) +ShouldMarkReparentedFramesDirty( +#ifdef DEBUG + nsContainerFrame* aOldParent, +#endif + nsIFrame* aNewParent, + ReparentingDirection aDirection) { +#ifdef DEBUG + MOZ_ASSERT(aOldParent->FirstInFlow() == aNewParent->FirstInFlow(), + "Reparenting should be between continuations of the same frame"); + if (aDirection != ReparentingDirection::Variable && + aOldParent->FirstInFlow() == aNewParent->FirstInFlow()) { + auto IndexInFlow = + [](const nsIFrame* f) { + int i = 0; while ((f = f->GetPrevInFlow())) { ++i; } return i; + }; + MOZ_ASSERT((IndexInFlow(aOldParent) < IndexInFlow(aNewParent)) == + (aDirection == ReparentingDirection::Forwards), + "Parents not in expected order"); + } +#endif // Frames going forward must have already been reflowed, or at least marked // dirty. Otherwise frames going backwards (or direction is unknown) may not // be marked dirty yet. @@ -642,7 +660,11 @@ static void ReparentFrame(nsIFrame* aFrame, nsContainerFrame* aOldParent, nsContainerFrame* aNewParent, ReparentingDirection aDirection) { - const bool markDirty = ShouldMarkReparentedFramesDirty(aNewParent, aDirection); + const bool markDirty = ShouldMarkReparentedFramesDirty( +#ifdef DEBUG + aOldParent, +#endif + aNewParent, aDirection); ReparentFrameInternal(aFrame, aOldParent, aNewParent, markDirty); } @@ -650,7 +672,11 @@ static void ReparentFrames(nsFrameList& aFrameList, nsContainerFrame* aOldParent, nsContainerFrame* aNewParent, ReparentingDirection aDirection) { - const bool markDirty = ShouldMarkReparentedFramesDirty(aNewParent, aDirection); + const bool markDirty = ShouldMarkReparentedFramesDirty( +#ifdef DEBUG + aOldParent, +#endif + aNewParent, aDirection); for (nsFrameList::Enumerator e(aFrameList); !e.AtEnd(); e.Next()) { ReparentFrameInternal(e.get(), aOldParent, aNewParent, markDirty); }