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:
Mats Palmgren 2016-03-11 17:39:27 +01:00
Родитель a808043f13
Коммит 3ab9def464
3 изменённых файлов: 79 добавлений и 40 удалений

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

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