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
This commit is contained in:
Ting-Yu Lin 2020-08-29 00:22:23 +00:00
Родитель 0076add365
Коммит 45b86ae08f
3 изменённых файлов: 36 добавлений и 16 удалений

Просмотреть файл

@ -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;

Просмотреть файл

@ -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<nsContainerFrame*>(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<nsContainerFrame*>(GetPrevInFlow())
@ -2936,8 +2933,7 @@ void nsOverflowContinuationTracker::SetupOverflowContList() {
nsContainerFrame* nif =
static_cast<nsContainerFrame*>(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<nsFrameList*>(
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<nsContainerFrame*>(GetPrevInFlow());
if (pif) {
const nsFrameList* oc = GetPropTableFrames(OverflowContainersProperty());
const nsFrameList* oc = GetOverflowContainers();
const nsFrameList* eoc =
GetPropTableFrames(ExcessOverflowContainersProperty());
const nsFrameList* pifEOC =

Просмотреть файл

@ -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