mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-18 15:55:36 +00:00
Bug 1625362 Part 2 - Move some helpers manipulating overflow lists from nsGridContainerFrame to nsContainerFrame. r=mats
We can utilize these helpers to implement flex item fragmentation. Differential Revision: https://phabricator.services.mozilla.com/D68491 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
97c3b1d8cb
commit
a2e0d00564
@ -1514,6 +1514,95 @@ bool nsContainerFrame::MoveOverflowToChildList() {
|
||||
return DrainSelfOverflowList() || result;
|
||||
}
|
||||
|
||||
void nsContainerFrame::MergeSortedOverflow(nsFrameList& aList) {
|
||||
if (aList.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(
|
||||
!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* overflow = GetOverflowFrames();
|
||||
if (overflow) {
|
||||
MergeSortedFrameLists(*overflow, aList, GetContent());
|
||||
} else {
|
||||
SetOverflowFrames(aList);
|
||||
}
|
||||
}
|
||||
|
||||
void nsContainerFrame::MergeSortedExcessOverflowContainers(nsFrameList& aList) {
|
||||
if (aList.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(
|
||||
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) {
|
||||
MergeSortedFrameLists(*eoc, aList, GetContent());
|
||||
} else {
|
||||
SetPropTableFrames(new (PresShell()) nsFrameList(aList),
|
||||
ExcessOverflowContainersProperty());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is aFrame1 a prev-continuation of aFrame2?
|
||||
*/
|
||||
static bool IsPrevContinuationOf(nsIFrame* aFrame1, nsIFrame* aFrame2) {
|
||||
nsIFrame* prev = aFrame2;
|
||||
while ((prev = prev->GetPrevContinuation())) {
|
||||
if (prev == aFrame1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void nsContainerFrame::MergeSortedFrameLists(nsFrameList& aDest,
|
||||
nsFrameList& aSrc,
|
||||
nsIContent* aCommonAncestor) {
|
||||
nsIFrame* dest = aDest.FirstChild();
|
||||
for (nsIFrame* src = aSrc.FirstChild(); src;) {
|
||||
if (!dest) {
|
||||
aDest.AppendFrames(nullptr, aSrc);
|
||||
break;
|
||||
}
|
||||
nsIContent* srcContent = src->GetContent();
|
||||
nsIContent* destContent = dest->GetContent();
|
||||
int32_t result = nsLayoutUtils::CompareTreePosition(srcContent, destContent,
|
||||
aCommonAncestor);
|
||||
if (MOZ_UNLIKELY(result == 0)) {
|
||||
// NOTE: we get here when comparing ::before/::after for the same element.
|
||||
if (MOZ_UNLIKELY(srcContent->IsGeneratedContentContainerForBefore())) {
|
||||
if (MOZ_LIKELY(!destContent->IsGeneratedContentContainerForBefore()) ||
|
||||
::IsPrevContinuationOf(src, dest)) {
|
||||
result = -1;
|
||||
}
|
||||
} else if (MOZ_UNLIKELY(
|
||||
srcContent->IsGeneratedContentContainerForAfter())) {
|
||||
if (MOZ_UNLIKELY(destContent->IsGeneratedContentContainerForAfter()) &&
|
||||
::IsPrevContinuationOf(src, dest)) {
|
||||
result = -1;
|
||||
}
|
||||
} else if (::IsPrevContinuationOf(src, dest)) {
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
if (result < 0) {
|
||||
// src should come before dest
|
||||
nsIFrame* next = src->GetNextSibling();
|
||||
aSrc.RemoveFrame(src);
|
||||
aDest.InsertFrame(nullptr, dest->GetPrevSibling(), src);
|
||||
src = next;
|
||||
} else {
|
||||
dest = dest->GetNextSibling();
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(aSrc.IsEmpty());
|
||||
}
|
||||
|
||||
bool nsContainerFrame::MoveInlineOverflowToChildList(nsIFrame* aLineContainer) {
|
||||
MOZ_ASSERT(aLineContainer,
|
||||
"Must have line container for moving inline overflows");
|
||||
|
@ -566,6 +566,39 @@ class nsContainerFrame : public nsSplittableFrame {
|
||||
*/
|
||||
bool MoveOverflowToChildList();
|
||||
|
||||
/**
|
||||
* Merge a sorted frame list into our overflow list. aList becomes empty after
|
||||
* this call.
|
||||
*/
|
||||
void MergeSortedOverflow(nsFrameList& aList);
|
||||
|
||||
/**
|
||||
* Merge a sorted frame list into our excess overflow containers list. aList
|
||||
* becomes empty after this call.
|
||||
*/
|
||||
void MergeSortedExcessOverflowContainers(nsFrameList& aList);
|
||||
|
||||
/**
|
||||
* Moves all frames from aSrc into aDest such that the resulting aDest
|
||||
* is still sorted in document content order and continuation order. aSrc
|
||||
* becomes empty after this call.
|
||||
*
|
||||
* Precondition: both |aSrc| and |aDest| must be sorted to begin with.
|
||||
* @param aCommonAncestor a hint for nsLayoutUtils::CompareTreePosition
|
||||
*/
|
||||
static void MergeSortedFrameLists(nsFrameList& aDest, nsFrameList& aSrc,
|
||||
nsIContent* aCommonAncestor);
|
||||
|
||||
/**
|
||||
* This is intended to be used as a ChildFrameMerger argument for
|
||||
* ReflowOverflowContainerChildren().
|
||||
*/
|
||||
static inline void MergeSortedFrameListsFor(nsFrameList& aDest,
|
||||
nsFrameList& aSrc,
|
||||
nsContainerFrame* aParent) {
|
||||
MergeSortedFrameLists(aDest, aSrc, aParent->GetContent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Basically same as MoveOverflowToChildList, except that this is for
|
||||
* handling inline children where children of prev-in-flow can be
|
||||
|
@ -367,72 +367,6 @@ TrackSize::StateBits nsGridContainerFrame::TrackSize::Initialize(
|
||||
return mState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is aFrame1 a prev-continuation of aFrame2?
|
||||
*/
|
||||
static bool IsPrevContinuationOf(nsIFrame* aFrame1, nsIFrame* aFrame2) {
|
||||
nsIFrame* prev = aFrame2;
|
||||
while ((prev = prev->GetPrevContinuation())) {
|
||||
if (prev == aFrame1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves all frames from aSrc into aDest such that the resulting aDest
|
||||
* is still sorted in document content order and continuation order.
|
||||
* Precondition: both |aSrc| and |aDest| must be sorted to begin with.
|
||||
* @param aCommonAncestor a hint for nsLayoutUtils::CompareTreePosition
|
||||
*/
|
||||
static void MergeSortedFrameLists(nsFrameList& aDest, nsFrameList& aSrc,
|
||||
nsIContent* aCommonAncestor) {
|
||||
nsIFrame* dest = aDest.FirstChild();
|
||||
for (nsIFrame* src = aSrc.FirstChild(); src;) {
|
||||
if (!dest) {
|
||||
aDest.AppendFrames(nullptr, aSrc);
|
||||
break;
|
||||
}
|
||||
nsIContent* srcContent = src->GetContent();
|
||||
nsIContent* destContent = dest->GetContent();
|
||||
int32_t result = nsLayoutUtils::CompareTreePosition(srcContent, destContent,
|
||||
aCommonAncestor);
|
||||
if (MOZ_UNLIKELY(result == 0)) {
|
||||
// NOTE: we get here when comparing ::before/::after for the same element.
|
||||
if (MOZ_UNLIKELY(srcContent->IsGeneratedContentContainerForBefore())) {
|
||||
if (MOZ_LIKELY(!destContent->IsGeneratedContentContainerForBefore()) ||
|
||||
::IsPrevContinuationOf(src, dest)) {
|
||||
result = -1;
|
||||
}
|
||||
} else if (MOZ_UNLIKELY(
|
||||
srcContent->IsGeneratedContentContainerForAfter())) {
|
||||
if (MOZ_UNLIKELY(destContent->IsGeneratedContentContainerForAfter()) &&
|
||||
::IsPrevContinuationOf(src, dest)) {
|
||||
result = -1;
|
||||
}
|
||||
} else if (::IsPrevContinuationOf(src, dest)) {
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
if (result < 0) {
|
||||
// src should come before dest
|
||||
nsIFrame* next = src->GetNextSibling();
|
||||
aSrc.RemoveFrame(src);
|
||||
aDest.InsertFrame(nullptr, dest->GetPrevSibling(), src);
|
||||
src = next;
|
||||
} else {
|
||||
dest = dest->GetNextSibling();
|
||||
}
|
||||
}
|
||||
MOZ_ASSERT(aSrc.IsEmpty());
|
||||
}
|
||||
|
||||
static void MergeSortedFrameListsFor(nsFrameList& aDest, nsFrameList& aSrc,
|
||||
nsContainerFrame* aParent) {
|
||||
MergeSortedFrameLists(aDest, aSrc, aParent->GetContent());
|
||||
}
|
||||
|
||||
/**
|
||||
* A LineRange can be definite or auto - when it's definite it represents
|
||||
* a consecutive set of tracks between a starting line and an ending line.
|
||||
@ -7185,7 +7119,7 @@ void nsGridContainerFrame::NormalizeChildLists() {
|
||||
AutoFrameListPtr overflow(PresContext(), prevInFlow->StealOverflowFrames());
|
||||
if (overflow) {
|
||||
ReparentFrames(*overflow, prevInFlow, this);
|
||||
::MergeSortedFrameLists(mFrames, *overflow, GetContent());
|
||||
MergeSortedFrameLists(mFrames, *overflow, GetContent());
|
||||
|
||||
// Move trailing next-in-flows into our overflow list.
|
||||
nsFrameList continuations;
|
||||
@ -7243,7 +7177,7 @@ void nsGridContainerFrame::NormalizeChildLists() {
|
||||
}
|
||||
f = next;
|
||||
}
|
||||
::MergeSortedFrameLists(mFrames, items, GetContent());
|
||||
MergeSortedFrameLists(mFrames, items, GetContent());
|
||||
if (ourOverflow->IsEmpty()) {
|
||||
DestroyOverflowList();
|
||||
}
|
||||
@ -7295,7 +7229,7 @@ void nsGridContainerFrame::NormalizeChildLists() {
|
||||
}
|
||||
nifChild = next;
|
||||
}
|
||||
::MergeSortedFrameLists(items, nifItems, GetContent());
|
||||
MergeSortedFrameLists(items, nifItems, GetContent());
|
||||
|
||||
if (!nif->HasAnyStateBits(NS_STATE_GRID_DID_PUSH_ITEMS)) {
|
||||
MOZ_ASSERT(!nifNeedPushedItem || mDidPushItemsBitMayLie,
|
||||
@ -7315,7 +7249,7 @@ void nsGridContainerFrame::NormalizeChildLists() {
|
||||
}
|
||||
nifChild = next;
|
||||
}
|
||||
::MergeSortedFrameLists(items, nifItems, GetContent());
|
||||
MergeSortedFrameLists(items, nifItems, GetContent());
|
||||
|
||||
nif->RemoveStateBits(NS_STATE_GRID_DID_PUSH_ITEMS);
|
||||
nif = static_cast<nsGridContainerFrame*>(nif->GetNextInFlow());
|
||||
@ -7349,7 +7283,7 @@ void nsGridContainerFrame::NormalizeChildLists() {
|
||||
MOZ_ASSERT(
|
||||
foundOwnPushedChild || !items.IsEmpty() || mDidPushItemsBitMayLie,
|
||||
"NS_STATE_GRID_DID_PUSH_ITEMS lied");
|
||||
::MergeSortedFrameLists(mFrames, items, GetContent());
|
||||
MergeSortedFrameLists(mFrames, items, GetContent());
|
||||
}
|
||||
}
|
||||
|
||||
@ -8116,7 +8050,7 @@ bool nsGridContainerFrame::DrainSelfOverflowList() {
|
||||
// there are also direct calls from the fctor (FindAppendPrevSibling).
|
||||
AutoFrameListPtr overflowFrames(PresContext(), StealOverflowFrames());
|
||||
if (overflowFrames) {
|
||||
::MergeSortedFrameLists(mFrames, *overflowFrames, GetContent());
|
||||
MergeSortedFrameLists(mFrames, *overflowFrames, GetContent());
|
||||
// We set a frame bit to push them again in Reflow() to avoid creating
|
||||
// multiple grid items per grid container fragment for the same content.
|
||||
AddStateBits(NS_STATE_GRID_HAS_CHILD_NIFS);
|
||||
@ -8371,40 +8305,6 @@ void nsGridContainerFrame::NoteNewChildren(ChildListID aListID,
|
||||
}
|
||||
}
|
||||
|
||||
void nsGridContainerFrame::MergeSortedOverflow(nsFrameList& aList) {
|
||||
if (aList.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(
|
||||
!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* overflow = GetOverflowFrames();
|
||||
if (overflow) {
|
||||
::MergeSortedFrameLists(*overflow, aList, GetContent());
|
||||
} else {
|
||||
SetOverflowFrames(aList);
|
||||
}
|
||||
}
|
||||
|
||||
void nsGridContainerFrame::MergeSortedExcessOverflowContainers(
|
||||
nsFrameList& aList) {
|
||||
if (aList.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(
|
||||
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) {
|
||||
::MergeSortedFrameLists(*eoc, aList, GetContent());
|
||||
} else {
|
||||
SetPropTableFrames(new (PresShell()) nsFrameList(aList),
|
||||
ExcessOverflowContainersProperty());
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ nsGridContainerFrame::FindItemInGridOrderResult
|
||||
nsGridContainerFrame::FindFirstItemInGridOrder(
|
||||
CSSOrderAwareFrameIterator& aIter, const nsTArray<GridItemInfo>& aGridItems,
|
||||
|
@ -363,11 +363,6 @@ class nsGridContainerFrame final : public nsContainerFrame {
|
||||
// Helper for AppendFrames / InsertFrames.
|
||||
void NoteNewChildren(ChildListID aListID, const nsFrameList& aFrameList);
|
||||
|
||||
// Helper to move child frames into the kOverflowList.
|
||||
void MergeSortedOverflow(nsFrameList& aList);
|
||||
// Helper to move child frames into the kExcessOverflowContainersList:.
|
||||
void MergeSortedExcessOverflowContainers(nsFrameList& aList);
|
||||
|
||||
bool GetBBaseline(BaselineSharingGroup aBaselineGroup,
|
||||
nscoord* aResult) const {
|
||||
*aResult = mBaseline[mozilla::eLogicalAxisBlock][aBaselineGroup];
|
||||
|
Loading…
Reference in New Issue
Block a user