Store the overflow out of flows as an nsFrameList. b=516974 r=bzbarsky

This commit is contained in:
Mats Palmgren 2009-09-24 04:39:21 +02:00
parent ee7731b8c9
commit cf4ae83f1a
2 changed files with 40 additions and 30 deletions

View File

@ -534,7 +534,8 @@ nsBlockFrame::GetChildList(nsIAtom* aListName) const
: nsFrameList::EmptyList();
}
else if (aListName == nsGkAtoms::overflowOutOfFlowList) {
return GetOverflowOutOfFlows();
const nsFrameList* list = GetOverflowOutOfFlows();
return list ? *list : nsFrameList::EmptyList();
}
else if (aListName == nsGkAtoms::floatList) {
return mFloats;
@ -4522,35 +4523,46 @@ nsBlockFrame::SetOverflowLines(nsLineList* aOverflowLines)
return rv;
}
nsFrameList
nsFrameList*
nsBlockFrame::GetOverflowOutOfFlows() const
{
if (!(GetStateBits() & NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS)) {
return nsFrameList();
return nsnull;
}
nsIFrame* result = static_cast<nsIFrame*>
(GetProperty(nsGkAtoms::overflowOutOfFlowsProperty));
nsFrameList* result =
GetPropTableFrames(PresContext(), nsGkAtoms::overflowOutOfFlowsProperty);
NS_ASSERTION(result, "value should always be non-empty when state set");
return nsFrameList(result, nsLayoutUtils::GetLastSibling(result));
return result;
}
// This takes ownership of the frames
void
nsBlockFrame::SetOverflowOutOfFlows(const nsFrameList& aList)
nsBlockFrame::SetOverflowOutOfFlows(const nsFrameList& aList,
nsFrameList* aPropValue)
{
NS_PRECONDITION(!!(GetStateBits() & NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS) ==
!!aPropValue, "state does not match value");
if (aList.IsEmpty()) {
if (!(GetStateBits() & NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS)) {
return;
}
#ifdef DEBUG
nsIFrame* result = static_cast<nsIFrame*>
#endif
(UnsetProperty(nsGkAtoms::overflowOutOfFlowsProperty));
NS_ASSERTION(result, "value should always be non-empty when state set");
nsFrameList* list =
RemovePropTableFrames(PresContext(),
nsGkAtoms::overflowOutOfFlowsProperty);
NS_ASSERTION(aPropValue == list, "prop value mismatch");
delete list;
RemoveStateBits(NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS);
} else {
SetProperty(nsGkAtoms::overflowOutOfFlowsProperty,
aList.FirstChild(), nsnull);
}
else if (GetStateBits() & NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS) {
NS_ASSERTION(aPropValue == GetPropTableFrames(PresContext(),
nsGkAtoms::overflowOutOfFlowsProperty),
"prop value mismatch");
*aPropValue = aList;
}
else {
SetPropTableFrames(PresContext(), new nsFrameList(aList),
nsGkAtoms::overflowOutOfFlowsProperty);
AddStateBits(NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS);
}
}
@ -6674,8 +6686,8 @@ nsBlockFrame::CheckFloats(nsBlockReflowState& aState)
}
#endif
nsFrameList oofs = GetOverflowOutOfFlows();
if (oofs.NotEmpty()) {
const nsFrameList* oofs = GetOverflowOutOfFlows();
if (oofs && oofs->NotEmpty()) {
// Floats that were pushed should be removed from our float
// manager. Otherwise the float manager's YMost or XMost might
// be larger than necessary, causing this block to get an
@ -6686,7 +6698,7 @@ nsBlockFrame::CheckFloats(nsBlockReflowState& aState)
// because we know from here on the float manager will only be
// used for its XMost and YMost, not to place new floats and
// lines.
aState.mFloatManager->RemoveTrailingRegions(oofs.FirstChild());
aState.mFloatManager->RemoveTrailingRegions(oofs->FirstChild());
}
}

View File

@ -677,30 +677,28 @@ protected:
* overflow list. It gives the client direct writable access to
* the frame list temporarily but ensures that property is only
* written back if absolutely necessary.
* @note currently we can ignore mList.mLastChild being different because
* the overflow OOFs are stored internally as a frame pointer property
* (the first child of the list).
*/
struct nsAutoOOFFrameList {
nsFrameList mList;
nsAutoOOFFrameList(nsBlockFrame* aBlock)
: mList(aBlock->GetOverflowOutOfFlows())
, mOldFirstChild(mList.FirstChild())
, mBlock(aBlock) {}
~nsAutoOOFFrameList() {
if (mList.FirstChild() != mOldFirstChild) {
mBlock->SetOverflowOutOfFlows(mList);
: mPropValue(aBlock->GetOverflowOutOfFlows())
, mBlock(aBlock) {
if (mPropValue) {
mList = *mPropValue;
}
}
~nsAutoOOFFrameList() {
mBlock->SetOverflowOutOfFlows(mList, mPropValue);
}
protected:
nsIFrame* const mOldFirstChild;
nsFrameList* const mPropValue;
nsBlockFrame* const mBlock;
};
friend struct nsAutoOOFFrameList;
nsFrameList GetOverflowOutOfFlows() const;
void SetOverflowOutOfFlows(const nsFrameList& aList);
nsFrameList* GetOverflowOutOfFlows() const;
void SetOverflowOutOfFlows(const nsFrameList& aList, nsFrameList* aPropValue);
#ifdef NS_DEBUG
void VerifyLines(PRBool aFinalCheckOK);