From 45b86ae08f116560212c726ec2b32ab78d5b9bbb Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Sat, 29 Aug 2020 00:22:23 +0000 Subject: [PATCH] Bug 1641085 Part 2 - Add APIs to manipulate overflow containers list. r=mats Not all APIs added in this patch are used immediately, but for the sake of completeness, they are all added. Their document will be updated in Part 3 after adding the relevant APIs for ExcessOverflowContainersProperty(). nsContainerFrame::DrainExcessOverflowContainersList() has several calls to set OverflowContainersProperty() whose life cycle need special attention. We will deal with them later in Part 4. Differential Revision: https://phabricator.services.mozilla.com/D88456 --- layout/generic/nsBlockFrame.cpp | 2 +- layout/generic/nsContainerFrame.cpp | 23 +++++++++-------------- layout/generic/nsContainerFrame.h | 27 ++++++++++++++++++++++++++- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 0a604ac770ed..f784353174d8 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -5169,7 +5169,7 @@ bool nsBlockFrame::DrainOverflowLines() { // prev-in-flow. We'll append these to mFrames to ensure the continuations // are ordered. auto HasOverflowContainers = [this]() -> bool { - return GetPropTableFrames(OverflowContainersProperty()) || + return GetOverflowContainers() || GetPropTableFrames(ExcessOverflowContainersProperty()); }; nsFrameList ocContinuations; diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp index 8dbd51ec779f..8469491db5c6 100644 --- a/layout/generic/nsContainerFrame.cpp +++ b/layout/generic/nsContainerFrame.cpp @@ -301,7 +301,7 @@ const nsFrameList& nsContainerFrame::GetChildList(ChildListID aListID) const { return list ? *list : nsFrameList::EmptyList(); } case kOverflowContainersList: { - nsFrameList* list = GetPropTableFrames(OverflowContainersProperty()); + nsFrameList* list = GetOverflowContainers(); return list ? *list : nsFrameList::EmptyList(); } case kExcessOverflowContainersList: { @@ -1397,7 +1397,7 @@ void nsContainerFrame::ReflowOverflowContainerChildren( void nsContainerFrame::DisplayOverflowContainers( nsDisplayListBuilder* aBuilder, const nsDisplayListSet& aLists) { - nsFrameList* overflowconts = GetPropTableFrames(OverflowContainersProperty()); + nsFrameList* overflowconts = GetOverflowContainers(); if (overflowconts) { for (nsIFrame* frame : *overflowconts) { BuildDisplayListForChild(aBuilder, frame, aLists); @@ -1439,7 +1439,7 @@ nsresult nsContainerFrame::StealFrame(nsIFrame* aChild) { if (!mFrames.ContainsFrame(aChild)) { nsFrameList* list = GetOverflowFrames(); if (!list || !list->ContainsFrame(aChild)) { - list = GetProperty(OverflowContainersProperty()); + list = GetOverflowContainers(); if (!list || !list->ContainsFrame(aChild)) { list = GetProperty(ExcessOverflowContainersProperty()); MOZ_ASSERT(list && list->ContainsFrame(aChild), @@ -1752,8 +1752,7 @@ bool nsContainerFrame::PushIncompleteChildren( // overflowIncompleteList into that list. Otherwise, merge it into our // excess overflow containers list, to be drained by our next-in-flow. auto* nif = static_cast(GetNextInFlow()); - nsFrameList* oc = - nif ? nif->GetPropTableFrames(OverflowContainersProperty()) : nullptr; + nsFrameList* oc = nif ? nif->GetOverflowContainers() : nullptr; if (oc) { ReparentFrames(overflowIncompleteList, this, nif); MergeSortedFrameLists(*oc, overflowIncompleteList, GetContent()); @@ -1839,8 +1838,7 @@ void nsContainerFrame::NormalizeChildLists() { f = next; } if (overflowContainers->IsEmpty()) { - (void)TakeProperty(OverflowContainersProperty()); - overflowContainers->Delete(PresShell()); + DestroyOverflowContainers(); } MergeSortedExcessOverflowContainers(moveToEOC); } @@ -2246,8 +2244,7 @@ bool nsContainerFrame::DrainAndMergeSelfOverflowList() { nsFrameList* nsContainerFrame::DrainExcessOverflowContainersList( ChildFrameMerger aMergeFunc) { - nsFrameList* overflowContainers = - GetPropTableFrames(OverflowContainersProperty()); + nsFrameList* overflowContainers = GetOverflowContainers(); NS_ASSERTION(!(overflowContainers && GetPrevInFlow() && static_cast(GetPrevInFlow()) @@ -2936,8 +2933,7 @@ void nsOverflowContinuationTracker::SetupOverflowContList() { nsContainerFrame* nif = static_cast(mParent->GetNextInFlow()); if (nif) { - mOverflowContList = - nif->GetPropTableFrames(nsContainerFrame::OverflowContainersProperty()); + mOverflowContList = nif->GetOverflowContainers(); if (mOverflowContList) { mParent = nif; SetUpListWalker(); @@ -3144,8 +3140,7 @@ void nsOverflowContinuationTracker::EndFinish(nsIFrame* aChild) { nsFrameList* eoc = mParent->GetProperty( nsContainerFrame::ExcessOverflowContainersProperty()); if (eoc != mOverflowContList) { - nsFrameList* oc = static_cast( - mParent->GetProperty(nsContainerFrame::OverflowContainersProperty())); + nsFrameList* oc = mParent->GetOverflowContainers(); if (oc != mOverflowContList) { // mOverflowContList was deleted mPrevOverflowCont = nullptr; @@ -3204,7 +3199,7 @@ void nsContainerFrame::SanityCheckChildListsBeforeReflow() const { // should be one of our children or be null. const auto* pif = static_cast(GetPrevInFlow()); if (pif) { - const nsFrameList* oc = GetPropTableFrames(OverflowContainersProperty()); + const nsFrameList* oc = GetOverflowContainers(); const nsFrameList* eoc = GetPropTableFrames(ExcessOverflowContainersProperty()); const nsFrameList* pifEOC = diff --git a/layout/generic/nsContainerFrame.h b/layout/generic/nsContainerFrame.h index 16f4d0e0b199..d445f2f68edb 100644 --- a/layout/generic/nsContainerFrame.h +++ b/layout/generic/nsContainerFrame.h @@ -541,11 +541,17 @@ class nsContainerFrame : public nsSplittableFrame { * still owned by this frame. A non-null return value indicates that the * list is nonempty. */ - nsFrameList* GetOverflowFrames() const { + [[nodiscard]] nsFrameList* GetOverflowFrames() const { nsFrameList* list = GetProperty(OverflowProperty()); NS_ASSERTION(!list || !list->IsEmpty(), "Unexpected empty overflow list"); return list; } + [[nodiscard]] nsFrameList* GetOverflowContainers() const { + nsFrameList* list = GetProperty(OverflowContainersProperty()); + NS_ASSERTION(!list || !list->IsEmpty(), + "Unexpected empty overflow containers list"); + return list; + } /** * As GetOverflowFrames, but removes the overflow frames property. The @@ -560,6 +566,11 @@ class nsContainerFrame : public nsSplittableFrame { NS_ASSERTION(!list || !list->IsEmpty(), "Unexpected empty overflow list"); return list; } + [[nodiscard]] nsFrameList* StealOverflowContainers() { + nsFrameList* list = TakeProperty(OverflowContainersProperty()); + NS_ASSERTION(!list || !list->IsEmpty(), "Unexpected empty overflow list"); + return list; + } /** * Set the overflow list. aOverflowFrames must not be an empty list. @@ -569,6 +580,15 @@ class nsContainerFrame : public nsSplittableFrame { SetProperty(OverflowProperty(), new (PresShell()) nsFrameList(std::move(aOverflowFrames))); } + void SetOverflowContainers(nsFrameList&& aOverflowContainers) { + MOZ_ASSERT(aOverflowContainers.NotEmpty(), "Shouldn't set an empty list!"); + MOZ_ASSERT(!GetProperty(OverflowContainersProperty()), + "Shouldn't override existing list!"); + MOZ_ASSERT(IsFrameOfType(nsIFrame::eCanContainOverflowContainers), + "This type of frame can't have overflow containers!"); + SetProperty(OverflowContainersProperty(), + new (PresShell()) nsFrameList(std::move(aOverflowContainers))); + } /** * Destroy the overflow list, which must be empty. @@ -578,6 +598,11 @@ class nsContainerFrame : public nsSplittableFrame { MOZ_ASSERT(list && list->IsEmpty()); list->Delete(PresShell()); } + void DestroyOverflowContainers() { + nsFrameList* list = TakeProperty(OverflowContainersProperty()); + MOZ_ASSERT(list && list->IsEmpty()); + list->Delete(PresShell()); + } /** * Moves any frames on both the prev-in-flow's overflow list and the