зеркало из https://github.com/mozilla/gecko-dev.git
Store the overflow out of flows as an nsFrameList. b=516974 r=bzbarsky
This commit is contained in:
Родитель
f32dfd96aa
Коммит
ce915e403f
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче