зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1144096 part 24 - [css-grid] Move the child frame merging code at the start of ReflowOverflowContainerChildren into a new method: DrainExcessOverflowContainersList. Make both take a param so that we can override how the OC child lists are merged together (normally just an Append; MergeSortedFrameLists for Grid). r=dholbert
This commit is contained in:
Родитель
a808043f13
Коммит
3ab9def464
|
@ -1230,46 +1230,12 @@ nsContainerFrame::ReflowOverflowContainerChildren(nsPresContext* aPres
|
|||
const nsHTMLReflowState& aReflowState,
|
||||
nsOverflowAreas& aOverflowRects,
|
||||
uint32_t aFlags,
|
||||
nsReflowStatus& aStatus)
|
||||
nsReflowStatus& aStatus,
|
||||
ChildFrameMerger aMergeFunc)
|
||||
{
|
||||
NS_PRECONDITION(aPresContext, "null pointer");
|
||||
|
||||
nsFrameList* overflowContainers =
|
||||
GetPropTableFrames(OverflowContainersProperty());
|
||||
|
||||
NS_ASSERTION(!(overflowContainers && GetPrevInFlow()
|
||||
&& static_cast<nsContainerFrame*>(GetPrevInFlow())
|
||||
->GetPropTableFrames(ExcessOverflowContainersProperty())),
|
||||
"conflicting overflow containers lists");
|
||||
|
||||
if (!overflowContainers) {
|
||||
// Drain excess from previnflow
|
||||
nsContainerFrame* prev = (nsContainerFrame*) GetPrevInFlow();
|
||||
if (prev) {
|
||||
nsFrameList* excessFrames =
|
||||
prev->RemovePropTableFrames(ExcessOverflowContainersProperty());
|
||||
if (excessFrames) {
|
||||
excessFrames->ApplySetParent(this);
|
||||
nsContainerFrame::ReparentFrameViewList(*excessFrames, prev, this);
|
||||
overflowContainers = excessFrames;
|
||||
SetPropTableFrames(overflowContainers, OverflowContainersProperty());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Our own excess overflow containers from a previous reflow can still be
|
||||
// present if our next-in-flow hasn't been reflown yet.
|
||||
nsFrameList* selfExcessOCFrames =
|
||||
RemovePropTableFrames(ExcessOverflowContainersProperty());
|
||||
if (selfExcessOCFrames) {
|
||||
if (overflowContainers) {
|
||||
overflowContainers->AppendFrames(nullptr, *selfExcessOCFrames);
|
||||
selfExcessOCFrames->Delete(aPresContext->PresShell());
|
||||
} else {
|
||||
overflowContainers = selfExcessOCFrames;
|
||||
SetPropTableFrames(overflowContainers, OverflowContainersProperty());
|
||||
}
|
||||
}
|
||||
nsFrameList* overflowContainers = DrainExcessOverflowContainersList(aMergeFunc);
|
||||
if (!overflowContainers) {
|
||||
return; // nothing to reflow
|
||||
}
|
||||
|
@ -1687,6 +1653,49 @@ nsContainerFrame::DrainSelfOverflowList()
|
|||
return false;
|
||||
}
|
||||
|
||||
nsFrameList*
|
||||
nsContainerFrame::DrainExcessOverflowContainersList(ChildFrameMerger aMergeFunc)
|
||||
{
|
||||
nsFrameList* overflowContainers =
|
||||
GetPropTableFrames(OverflowContainersProperty());
|
||||
|
||||
NS_ASSERTION(!(overflowContainers && GetPrevInFlow()
|
||||
&& static_cast<nsContainerFrame*>(GetPrevInFlow())
|
||||
->GetPropTableFrames(ExcessOverflowContainersProperty())),
|
||||
"conflicting overflow containers lists");
|
||||
|
||||
if (!overflowContainers) {
|
||||
// Drain excess from previnflow
|
||||
nsContainerFrame* prev = (nsContainerFrame*) GetPrevInFlow();
|
||||
if (prev) {
|
||||
nsFrameList* excessFrames =
|
||||
prev->RemovePropTableFrames(ExcessOverflowContainersProperty());
|
||||
if (excessFrames) {
|
||||
excessFrames->ApplySetParent(this);
|
||||
nsContainerFrame::ReparentFrameViewList(*excessFrames, prev, this);
|
||||
overflowContainers = excessFrames;
|
||||
SetPropTableFrames(overflowContainers, OverflowContainersProperty());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Our own excess overflow containers from a previous reflow can still be
|
||||
// present if our next-in-flow hasn't been reflown yet.
|
||||
nsFrameList* selfExcessOCFrames =
|
||||
RemovePropTableFrames(ExcessOverflowContainersProperty());
|
||||
if (selfExcessOCFrames) {
|
||||
if (overflowContainers) {
|
||||
aMergeFunc(*overflowContainers, *selfExcessOCFrames, this);
|
||||
selfExcessOCFrames->Delete(PresContext()->PresShell());
|
||||
} else {
|
||||
overflowContainers = selfExcessOCFrames;
|
||||
SetPropTableFrames(overflowContainers, OverflowContainersProperty());
|
||||
}
|
||||
}
|
||||
|
||||
return overflowContainers;
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsContainerFrame::GetNextInFlowChild(ContinuationTraversingState& aState,
|
||||
bool* aIsInOverflow)
|
||||
|
|
|
@ -350,6 +350,15 @@ public:
|
|||
|
||||
friend class nsOverflowContinuationTracker;
|
||||
|
||||
typedef void (*ChildFrameMerger)(nsFrameList& aDest, nsFrameList& aSrc,
|
||||
nsContainerFrame* aParent);
|
||||
static inline void DefaultChildFrameMerge(nsFrameList& aDest,
|
||||
nsFrameList& aSrc,
|
||||
nsContainerFrame* aParent)
|
||||
{
|
||||
aDest.AppendFrames(nullptr, aSrc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reflow overflow container children. They are invisible to normal reflow
|
||||
* (i.e. don't affect sizing or placement of other children) and inherit
|
||||
|
@ -372,13 +381,16 @@ public:
|
|||
* making sure they are stored properly in the overflow container lists.
|
||||
* The nsOverflowContinuationTracker helper class should be used for this.
|
||||
*
|
||||
* (aFlags just gets passed through to ReflowChild)
|
||||
* @param aFlags is passed through to ReflowChild
|
||||
* @param aMergeFunc is passed to DrainExcessOverflowContainersList
|
||||
*/
|
||||
void ReflowOverflowContainerChildren(nsPresContext* aPresContext,
|
||||
const nsHTMLReflowState& aReflowState,
|
||||
nsOverflowAreas& aOverflowRects,
|
||||
uint32_t aFlags,
|
||||
nsReflowStatus& aStatus);
|
||||
nsReflowStatus& aStatus,
|
||||
ChildFrameMerger aMergeFunc =
|
||||
DefaultChildFrameMerge);
|
||||
|
||||
/**
|
||||
* Move any frames on our overflow list to the end of our principal list.
|
||||
|
@ -386,6 +398,16 @@ public:
|
|||
*/
|
||||
virtual bool DrainSelfOverflowList() override;
|
||||
|
||||
|
||||
/**
|
||||
* Move all frames on our prev-in-flow's and our own ExcessOverflowContainers
|
||||
* lists to our OverflowContainers list. If there are frames on multiple
|
||||
* lists they are merged using aMergeFunc.
|
||||
* @return a pointer to our OverflowContainers list, if any
|
||||
*/
|
||||
nsFrameList* DrainExcessOverflowContainersList(ChildFrameMerger aMergeFunc =
|
||||
DefaultChildFrameMerge);
|
||||
|
||||
/**
|
||||
* Removes aChild without destroying it and without requesting reflow.
|
||||
* Continuations are not affected. Checks the primary and overflow
|
||||
|
|
|
@ -254,6 +254,13 @@ MergeSortedFrameLists(nsFrameList& aDest, nsFrameList& aSrc,
|
|||
MOZ_ASSERT(aSrc.IsEmpty());
|
||||
}
|
||||
|
||||
static void
|
||||
MergeSortedFrameListsFor(nsFrameList& aDest, nsFrameList& aSrc,
|
||||
nsContainerFrame* aParent)
|
||||
{
|
||||
MergeSortedFrameLists(aDest, aSrc, aParent->GetContent());
|
||||
}
|
||||
|
||||
class nsGridContainerFrame::GridItemCSSOrderIterator
|
||||
{
|
||||
public:
|
||||
|
@ -4725,7 +4732,8 @@ nsGridContainerFrame::ReflowChildren(GridReflowState& aState,
|
|||
nsReflowStatus ocStatus = NS_FRAME_COMPLETE;
|
||||
if (GetPrevInFlow()) {
|
||||
ReflowOverflowContainerChildren(PresContext(), *aState.mReflowState,
|
||||
ocBounds, 0, ocStatus);
|
||||
ocBounds, 0, ocStatus,
|
||||
MergeSortedFrameListsFor);
|
||||
}
|
||||
|
||||
WritingMode wm = aState.mReflowState->GetWritingMode();
|
||||
|
|
Загрузка…
Ссылка в новой задаче