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
Родитель f32dfd96aa
Коммит ce915e403f
2 изменённых файлов: 40 добавлений и 30 удалений

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

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

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

@ -677,30 +677,28 @@ protected:
* overflow list. It gives the client direct writable access to * overflow list. It gives the client direct writable access to
* the frame list temporarily but ensures that property is only * the frame list temporarily but ensures that property is only
* written back if absolutely necessary. * 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 { struct nsAutoOOFFrameList {
nsFrameList mList; nsFrameList mList;
nsAutoOOFFrameList(nsBlockFrame* aBlock) nsAutoOOFFrameList(nsBlockFrame* aBlock)
: mList(aBlock->GetOverflowOutOfFlows()) : mPropValue(aBlock->GetOverflowOutOfFlows())
, mOldFirstChild(mList.FirstChild()) , mBlock(aBlock) {
, mBlock(aBlock) {} if (mPropValue) {
~nsAutoOOFFrameList() { mList = *mPropValue;
if (mList.FirstChild() != mOldFirstChild) {
mBlock->SetOverflowOutOfFlows(mList);
} }
} }
~nsAutoOOFFrameList() {
mBlock->SetOverflowOutOfFlows(mList, mPropValue);
}
protected: protected:
nsIFrame* const mOldFirstChild; nsFrameList* const mPropValue;
nsBlockFrame* const mBlock; nsBlockFrame* const mBlock;
}; };
friend struct nsAutoOOFFrameList; friend struct nsAutoOOFFrameList;
nsFrameList GetOverflowOutOfFlows() const; nsFrameList* GetOverflowOutOfFlows() const;
void SetOverflowOutOfFlows(const nsFrameList& aList); void SetOverflowOutOfFlows(const nsFrameList& aList, nsFrameList* aPropValue);
#ifdef NS_DEBUG #ifdef NS_DEBUG
void VerifyLines(PRBool aFinalCheckOK); void VerifyLines(PRBool aFinalCheckOK);