зеркало из 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();
|
: 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);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче