Bug 1641085 Part 3 - Add APIs to manipulate excess overflow containers list. r=mats

This patch is similar to Part 2, but for adding APIs for
ExcessOverflowContainersProperty().

Differential Revision: https://phabricator.services.mozilla.com/D88457
This commit is contained in:
Ting-Yu Lin 2020-08-29 00:22:31 +00:00
Родитель 45b86ae08f
Коммит 9cb3f93c40
4 изменённых файлов: 70 добавлений и 37 удалений

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

@ -914,12 +914,10 @@ void nsFieldSetFrame::EnsureChildContinuation(nsIFrame* aChild,
}
}
if (aStatus.IsOverflowIncomplete()) {
if (nsFrameList* eoc =
GetPropTableFrames(ExcessOverflowContainersProperty())) {
if (nsFrameList* eoc = GetExcessOverflowContainers()) {
eoc->AppendFrames(nullptr, nifs);
} else {
SetPropTableFrames(new (PresShell()) nsFrameList(nifs),
ExcessOverflowContainersProperty());
SetExcessOverflowContainers(std::move(nifs));
}
} else {
if (nsFrameList* oc = GetOverflowFrames()) {

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

@ -5169,8 +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 GetOverflowContainers() ||
GetPropTableFrames(ExcessOverflowContainersProperty());
return GetOverflowContainers() || GetExcessOverflowContainers();
};
nsFrameList ocContinuations;
if (HasOverflowContainers()) {

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

@ -305,8 +305,7 @@ const nsFrameList& nsContainerFrame::GetChildList(ChildListID aListID) const {
return list ? *list : nsFrameList::EmptyList();
}
case kExcessOverflowContainersList: {
nsFrameList* list =
GetPropTableFrames(ExcessOverflowContainersProperty());
nsFrameList* list = GetExcessOverflowContainers();
return list ? *list : nsFrameList::EmptyList();
}
case kBackdropList: {
@ -1441,7 +1440,7 @@ nsresult nsContainerFrame::StealFrame(nsIFrame* aChild) {
if (!list || !list->ContainsFrame(aChild)) {
list = GetOverflowContainers();
if (!list || !list->ContainsFrame(aChild)) {
list = GetProperty(ExcessOverflowContainersProperty());
list = GetExcessOverflowContainers();
MOZ_ASSERT(list && list->ContainsFrame(aChild),
"aChild isn't our child"
" or on a frame list not supported by StealFrame");
@ -2053,12 +2052,10 @@ void nsContainerFrame::MergeSortedExcessOverflowContainers(nsFrameList& aList) {
aList.FirstChild()->HasAnyStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER),
"this is the wrong list to put this child frame");
MOZ_ASSERT(aList.FirstChild()->GetParent() == this);
nsFrameList* eoc = GetPropTableFrames(ExcessOverflowContainersProperty());
if (eoc) {
if (nsFrameList* eoc = GetExcessOverflowContainers()) {
MergeSortedFrameLists(*eoc, aList, GetContent());
} else {
SetPropTableFrames(new (PresShell()) nsFrameList(aList),
ExcessOverflowContainersProperty());
SetExcessOverflowContainers(std::move(aList));
}
}
@ -2248,7 +2245,7 @@ nsFrameList* nsContainerFrame::DrainExcessOverflowContainersList(
NS_ASSERTION(!(overflowContainers && GetPrevInFlow() &&
static_cast<nsContainerFrame*>(GetPrevInFlow())
->GetPropTableFrames(ExcessOverflowContainersProperty())),
->GetExcessOverflowContainers()),
"conflicting overflow containers lists");
if (!overflowContainers) {
@ -2940,8 +2937,7 @@ void nsOverflowContinuationTracker::SetupOverflowContList() {
}
}
if (!mOverflowContList) {
mOverflowContList = mParent->GetPropTableFrames(
nsContainerFrame::ExcessOverflowContainersProperty());
mOverflowContList = mParent->GetExcessOverflowContainers();
if (mOverflowContList) {
SetUpListWalker();
}
@ -3044,10 +3040,14 @@ nsresult nsOverflowContinuationTracker::Insert(nsIFrame* aOverflowCont,
aOverflowCont->AddStateBits(NS_FRAME_IS_OVERFLOW_CONTAINER);
}
if (!mOverflowContList) {
// Note: We don't use SetExcessOverflowContainers() since it requires
// setting a non-empty list. It's OK to manually set an empty list to
// ExcessOverflowContainersProperty() because we are going to insert
// aOverflowCont to mOverflowContList below, which guarantees an nonempty
// list in ExcessOverflowContainersProperty().
mOverflowContList = new (presContext->PresShell()) nsFrameList();
mParent->SetPropTableFrames(
mOverflowContList,
nsContainerFrame::ExcessOverflowContainersProperty());
mParent->SetProperty(nsContainerFrame::ExcessOverflowContainersProperty(),
mOverflowContList);
SetUpListWalker();
}
if (aOverflowCont->GetParent() != mParent) {
@ -3137,8 +3137,7 @@ void nsOverflowContinuationTracker::EndFinish(nsIFrame* aChild) {
return;
}
// Forget mOverflowContList if it was deleted.
nsFrameList* eoc = mParent->GetProperty(
nsContainerFrame::ExcessOverflowContainersProperty());
nsFrameList* eoc = mParent->GetExcessOverflowContainers();
if (eoc != mOverflowContList) {
nsFrameList* oc = mParent->GetOverflowContainers();
if (oc != mOverflowContList) {
@ -3200,10 +3199,8 @@ void nsContainerFrame::SanityCheckChildListsBeforeReflow() const {
const auto* pif = static_cast<nsContainerFrame*>(GetPrevInFlow());
if (pif) {
const nsFrameList* oc = GetOverflowContainers();
const nsFrameList* eoc =
GetPropTableFrames(ExcessOverflowContainersProperty());
const nsFrameList* pifEOC =
pif->GetPropTableFrames(ExcessOverflowContainersProperty());
const nsFrameList* eoc = GetExcessOverflowContainers();
const nsFrameList* pifEOC = pif->GetExcessOverflowContainers();
for (const nsIFrame* child : pif->GetChildList(kPrincipalList)) {
const nsIFrame* childNIF = child->GetNextInFlow();
MOZ_ASSERT(!childNIF || mFrames.ContainsFrame(childNIF) ||

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

@ -536,10 +536,12 @@ class nsContainerFrame : public nsSplittableFrame {
*/
/**
* Get the frames on the overflow list. Can return null if there are no
* overflow frames. The caller does NOT take ownership of the list; it's
* still owned by this frame. A non-null return value indicates that the
* list is nonempty.
* Get the frames on the overflow list, overflow containers list, or excess
* overflow containers list. Can return null if there are no frames in the
* list.
*
* The caller does NOT take ownership of the list; it's still owned by this
* frame. A non-null return value indicates that the list is non-empty.
*/
[[nodiscard]] nsFrameList* GetOverflowFrames() const {
nsFrameList* list = GetProperty(OverflowProperty());
@ -552,14 +554,22 @@ class nsContainerFrame : public nsSplittableFrame {
"Unexpected empty overflow containers list");
return list;
}
[[nodiscard]] nsFrameList* GetExcessOverflowContainers() const {
nsFrameList* list = GetProperty(ExcessOverflowContainersProperty());
NS_ASSERTION(!list || !list->IsEmpty(),
"Unexpected empty overflow containers list");
return list;
}
/**
* As GetOverflowFrames, but removes the overflow frames property. The
* caller is responsible for deleting nsFrameList and either passing
* ownership of the frames to someone else or destroying the frames.
* A non-null return value indicates that the list is nonempty. The
* recommended way to use this function it to assign its return value
* into an AutoFrameListPtr.
* Same as the Get methods above, but also remove and the property from this
* frame.
*
* The caller is responsible for deleting nsFrameList and either passing
* ownership of the frames to someone else or destroying the frames. A
* non-null return value indicates that the list is non-empty. The recommended
* way to use this function it to assign its return value into an
* AutoFrameListPtr.
*/
[[nodiscard]] nsFrameList* StealOverflowFrames() {
nsFrameList* list = TakeProperty(OverflowProperty());
@ -571,9 +581,17 @@ class nsContainerFrame : public nsSplittableFrame {
NS_ASSERTION(!list || !list->IsEmpty(), "Unexpected empty overflow list");
return list;
}
[[nodiscard]] nsFrameList* StealExcessOverflowContainers() {
nsFrameList* list = TakeProperty(ExcessOverflowContainersProperty());
NS_ASSERTION(!list || !list->IsEmpty(), "Unexpected empty overflow list");
return list;
}
/**
* Set the overflow list. aOverflowFrames must not be an empty list.
* Set the overflow list, overflow containers list, or excess overflow
* containers list. The argument must be a *non-empty* list.
*
* After this operation, the argument becomes an empty list.
*/
void SetOverflowFrames(nsFrameList&& aOverflowFrames) {
MOZ_ASSERT(aOverflowFrames.NotEmpty(), "Shouldn't be called");
@ -589,9 +607,25 @@ class nsContainerFrame : public nsSplittableFrame {
SetProperty(OverflowContainersProperty(),
new (PresShell()) nsFrameList(std::move(aOverflowContainers)));
}
void SetExcessOverflowContainers(nsFrameList&& aExcessOverflowContainers) {
MOZ_ASSERT(aExcessOverflowContainers.NotEmpty(),
"Shouldn't set an empty list!");
MOZ_ASSERT(!GetProperty(ExcessOverflowContainersProperty()),
"Shouldn't override existing list!");
MOZ_ASSERT(IsFrameOfType(nsIFrame::eCanContainOverflowContainers),
"This type of frame can't have overflow containers!");
SetProperty(ExcessOverflowContainersProperty(),
new (PresShell())
nsFrameList(std::move(aExcessOverflowContainers)));
}
/**
* Destroy the overflow list, which must be empty.
* Destroy the overflow list, overflow containers list, or excess overflow
* containers list.
*
* The list to be destroyed must be empty. That is, the caller is responsible
* for either passing ownership of the frames to someone else or destroying
* the frames before calling these methods.
*/
void DestroyOverflowList() {
nsFrameList* list = RemovePropTableFrames(OverflowProperty());
@ -603,6 +637,11 @@ class nsContainerFrame : public nsSplittableFrame {
MOZ_ASSERT(list && list->IsEmpty());
list->Delete(PresShell());
}
void DestroyExcessOverflowContainers() {
nsFrameList* list = TakeProperty(ExcessOverflowContainersProperty());
MOZ_ASSERT(list && list->IsEmpty());
list->Delete(PresShell());
}
/**
* Moves any frames on both the prev-in-flow's overflow list and the