зеркало из https://github.com/mozilla/pjs.git
Bug 230417. When a placeholder frame lands in a block's overflowList, put its out of flow frame in a new child list, overflowOutOfFlowsList
This commit is contained in:
Родитель
0cc421f07a
Коммит
8d9033c380
|
@ -82,6 +82,7 @@ LAYOUT_ATOM(editorDisplayList, "EditorDisplay-List")
|
|||
LAYOUT_ATOM(fixedList, "Fixed-list")
|
||||
LAYOUT_ATOM(floatList, "Float-list")
|
||||
LAYOUT_ATOM(overflowList, "Overflow-list")
|
||||
LAYOUT_ATOM(overflowOutOfFlowList, "OverflowOutOfFlow-list")
|
||||
LAYOUT_ATOM(popupList, "Popup-list")
|
||||
|
||||
LAYOUT_ATOM(commentTagName, "__moz_comment")
|
||||
|
@ -139,6 +140,7 @@ LAYOUT_ATOM(maxElementWidthProperty, "MaxElementWidthProperty") // nscoord*
|
|||
LAYOUT_ATOM(overflowAreaProperty, "OverflowArea") // nsRect*
|
||||
LAYOUT_ATOM(overflowProperty, "OverflowProperty") // list of nsIFrame*
|
||||
LAYOUT_ATOM(overflowLinesProperty, "OverflowLinesProperty") // list of nsLineBox*
|
||||
LAYOUT_ATOM(overflowOutOfFlowsProperty, "OverflowOutOfFlowsProperty") // nsFrameList*
|
||||
LAYOUT_ATOM(overflowPlaceholdersProperty, "OverflowPlaceholdersProperty") // nsPlaceholder*
|
||||
LAYOUT_ATOM(rowUnpaginatedHeightProperty, "RowUnpaginatedHeightProperty") // nscoord*
|
||||
LAYOUT_ATOM(spaceManagerProperty, "SpaceManagerProperty") // the space manager for a block
|
||||
|
|
|
@ -82,6 +82,7 @@ LAYOUT_ATOM(editorDisplayList, "EditorDisplay-List")
|
|||
LAYOUT_ATOM(fixedList, "Fixed-list")
|
||||
LAYOUT_ATOM(floatList, "Float-list")
|
||||
LAYOUT_ATOM(overflowList, "Overflow-list")
|
||||
LAYOUT_ATOM(overflowOutOfFlowList, "OverflowOutOfFlow-list")
|
||||
LAYOUT_ATOM(popupList, "Popup-list")
|
||||
|
||||
LAYOUT_ATOM(commentTagName, "__moz_comment")
|
||||
|
@ -139,6 +140,7 @@ LAYOUT_ATOM(maxElementWidthProperty, "MaxElementWidthProperty") // nscoord*
|
|||
LAYOUT_ATOM(overflowAreaProperty, "OverflowArea") // nsRect*
|
||||
LAYOUT_ATOM(overflowProperty, "OverflowProperty") // list of nsIFrame*
|
||||
LAYOUT_ATOM(overflowLinesProperty, "OverflowLinesProperty") // list of nsLineBox*
|
||||
LAYOUT_ATOM(overflowOutOfFlowsProperty, "OverflowOutOfFlowsProperty") // nsFrameList*
|
||||
LAYOUT_ATOM(overflowPlaceholdersProperty, "OverflowPlaceholdersProperty") // nsPlaceholder*
|
||||
LAYOUT_ATOM(rowUnpaginatedHeightProperty, "RowUnpaginatedHeightProperty") // nscoord*
|
||||
LAYOUT_ATOM(spaceManagerProperty, "SpaceManagerProperty") // the space manager for a block
|
||||
|
|
|
@ -304,6 +304,11 @@ nsBlockFrame::Destroy(nsIPresContext* aPresContext)
|
|||
if (overflowLines) {
|
||||
nsLineBox::DeleteLineList(aPresContext, *overflowLines);
|
||||
}
|
||||
nsFrameList* overflowOutOfFlows = GetOverflowOutOfFlows(PR_TRUE);
|
||||
if (overflowOutOfFlows) {
|
||||
overflowOutOfFlows->DestroyFrames(aPresContext);
|
||||
delete overflowOutOfFlows;
|
||||
}
|
||||
|
||||
return nsBlockFrameSuper::Destroy(aPresContext);
|
||||
}
|
||||
|
@ -477,6 +482,10 @@ nsBlockFrame::GetFirstChild(nsIAtom* aListName) const
|
|||
nsLineList* overflowLines = GetOverflowLines(GetPresContext(), PR_FALSE);
|
||||
return overflowLines ? overflowLines->front()->mFirstChild : nsnull;
|
||||
}
|
||||
else if (aListName == nsLayoutAtoms::overflowOutOfFlowList) {
|
||||
nsFrameList* oof = GetOverflowOutOfFlows(PR_FALSE);
|
||||
return oof ? oof->FirstChild() : nsnull;
|
||||
}
|
||||
else if (aListName == nsLayoutAtoms::floatList) {
|
||||
return mFloats.FirstChild();
|
||||
}
|
||||
|
@ -498,6 +507,8 @@ nsBlockFrame::GetAdditionalChildListName(PRInt32 aIndex) const
|
|||
return nsLayoutAtoms::bulletList;
|
||||
case NS_BLOCK_FRAME_OVERFLOW_LIST_INDEX:
|
||||
return nsLayoutAtoms::overflowList;
|
||||
case NS_BLOCK_FRAME_OVERFLOW_OOF_LIST_INDEX:
|
||||
return nsLayoutAtoms::overflowOutOfFlowList;
|
||||
case NS_BLOCK_FRAME_ABSOLUTE_LIST_INDEX:
|
||||
return mAbsoluteContainer.GetChildListName();
|
||||
default:
|
||||
|
@ -4205,7 +4216,6 @@ nsBlockFrame::PushLines(nsBlockReflowState& aState,
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
// The overflowLines property is stored as a pointer to a line list,
|
||||
// which must be deleted. However, the following functions all maintain
|
||||
// the invariant that the property is never set if the list is empty.
|
||||
|
@ -4240,26 +4250,6 @@ nsBlockFrame::DrainOverflowLines(nsIPresContext* aPresContext)
|
|||
// present in the lines, so their views can be reparented?
|
||||
nsHTMLContainerFrame::ReparentFrameView(aPresContext, frame, prevBlock, this);
|
||||
|
||||
// If the frame we are looking at is a placeholder for a float, we
|
||||
// need to reparent both it's out-of-flow frame and any views it has.
|
||||
//
|
||||
// Note: A floating table (example: style="position: relative; float: right")
|
||||
// is an example of an out-of-flow frame with a view
|
||||
|
||||
// XXXldb What about a placeholder within an inline or block descendant?
|
||||
|
||||
if (nsLayoutAtoms::placeholderFrame == frame->GetType()) {
|
||||
nsIFrame *outOfFlowFrame =
|
||||
NS_STATIC_CAST(nsPlaceholderFrame*, frame)->GetOutOfFlowFrame();
|
||||
if (!outOfFlowFrame->GetStyleDisplay()->IsAbsolutelyPositioned()) {
|
||||
// It's not an absolute or fixed positioned frame, so it
|
||||
// must be a float!
|
||||
outOfFlowFrame->SetParent(this);
|
||||
nsHTMLContainerFrame::ReparentFrameView(aPresContext,
|
||||
outOfFlowFrame, prevBlock, this);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the next frame
|
||||
lastFrame = frame;
|
||||
frame = frame->GetNextSibling();
|
||||
|
@ -4275,6 +4265,20 @@ nsBlockFrame::DrainOverflowLines(nsIPresContext* aPresContext)
|
|||
mLines.splice(mLines.begin(), *overflowLines);
|
||||
NS_ASSERTION(overflowLines->empty(), "splice should empty list");
|
||||
delete overflowLines;
|
||||
|
||||
// Out-of-flow floats need to be reparented too.
|
||||
nsFrameList* overflowOutOfFlows = prevBlock->GetOverflowOutOfFlows(PR_TRUE);
|
||||
if (overflowOutOfFlows) {
|
||||
for (nsIFrame* f = overflowOutOfFlows->FirstChild(); f;
|
||||
f = f->GetNextSibling()) {
|
||||
f->SetParent(this);
|
||||
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented
|
||||
nsHTMLContainerFrame::ReparentFrameView(aPresContext, f, prevBlock, this);
|
||||
}
|
||||
delete overflowOutOfFlows;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4295,6 +4299,14 @@ nsBlockFrame::DrainOverflowLines(nsIPresContext* aPresContext)
|
|||
mLines.splice(mLines.end(), *overflowLines);
|
||||
drained = PR_TRUE;
|
||||
delete overflowLines;
|
||||
|
||||
// Likewise, drain our own overflow out-of-flows. We don't need to
|
||||
// reparent them since they're already our children. We don't need
|
||||
// to put them on any child list since BuildFloatList will put
|
||||
// them on some child list. All we need to do is remove the
|
||||
// property.
|
||||
nsFrameList* overflowOutOfFlows = GetOverflowOutOfFlows(PR_TRUE);
|
||||
delete overflowOutOfFlows;
|
||||
}
|
||||
return drained;
|
||||
}
|
||||
|
@ -4341,6 +4353,36 @@ nsBlockFrame::SetOverflowLines(nsIPresContext* aPresContext,
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsFrameList*
|
||||
nsBlockFrame::GetOverflowOutOfFlows(PRBool aRemoveProperty) const
|
||||
{
|
||||
return NS_STATIC_CAST(nsFrameList*,
|
||||
GetProperty(GetPresContext(), nsLayoutAtoms::overflowOutOfFlowsProperty,
|
||||
aRemoveProperty));
|
||||
}
|
||||
|
||||
// Destructor function for the overflowPlaceholders frame property
|
||||
static void
|
||||
DestroyOverflowOOFs(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue)
|
||||
{
|
||||
NS_NOTREACHED("This helper method should never be called!");
|
||||
delete NS_STATIC_CAST(nsFrameList*, aPropertyValue);
|
||||
}
|
||||
|
||||
// This takes ownership of aFloaters.
|
||||
nsresult
|
||||
nsBlockFrame::SetOverflowOutOfFlows(nsFrameList* aOOFs)
|
||||
{
|
||||
nsresult rv = SetProperty(GetPresContext(), nsLayoutAtoms::overflowOutOfFlowsProperty,
|
||||
aOOFs, DestroyOverflowOOFs);
|
||||
// Verify that we didn't overwrite an existing overflow list
|
||||
NS_ASSERTION(rv != NS_IFRAME_MGR_PROP_OVERWRITTEN, "existing overflow float list");
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsFrameList*
|
||||
nsBlockFrame::GetOverflowPlaceholders(nsIPresContext* aPresContext,
|
||||
PRBool aRemoveProperty) const
|
||||
|
@ -6370,6 +6412,8 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
|
|||
void
|
||||
nsBlockFrame::BuildFloatList()
|
||||
{
|
||||
// Accumulate float list into mFloats.
|
||||
// Use the float cache to speed up searching the lines for floats.
|
||||
nsIFrame* head = nsnull;
|
||||
nsIFrame* current = nsnull;
|
||||
for (line_iterator line = begin_lines(), line_end = end_lines();
|
||||
|
@ -6379,10 +6423,9 @@ nsBlockFrame::BuildFloatList()
|
|||
nsFloatCache* fc = line->GetFirstFloat();
|
||||
while (fc) {
|
||||
nsIFrame* floatFrame = fc->mPlaceholder->GetOutOfFlowFrame();
|
||||
if (nsnull == head) {
|
||||
if (!head) {
|
||||
current = head = floatFrame;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
current->SetNextSibling(floatFrame);
|
||||
current = floatFrame;
|
||||
}
|
||||
|
@ -6392,10 +6435,51 @@ nsBlockFrame::BuildFloatList()
|
|||
}
|
||||
|
||||
// Terminate end of float list just in case a float was removed
|
||||
if (nsnull != current) {
|
||||
if (current) {
|
||||
current->SetNextSibling(nsnull);
|
||||
}
|
||||
mFloats.SetFrames(head);
|
||||
|
||||
// ensure that the floats in the overflow lines are put on a child list
|
||||
// and not dropped from the frame tree!
|
||||
// Note that overflow lines do not have any float cache set up for them,
|
||||
// because the float cache contains only laid-out floats
|
||||
nsLineList* overflowLines = GetOverflowLines(GetPresContext(), PR_FALSE);
|
||||
if (overflowLines) {
|
||||
head = nsnull;
|
||||
current = nsnull;
|
||||
|
||||
nsIFrame* frame = overflowLines->front()->mFirstChild;
|
||||
while (frame) {
|
||||
if (nsLayoutAtoms::placeholderFrame == frame->GetType()) {
|
||||
nsIFrame *outOfFlowFrame = NS_STATIC_CAST(nsPlaceholderFrame*, frame)->GetOutOfFlowFrame();
|
||||
if (outOfFlowFrame &&
|
||||
!outOfFlowFrame->GetStyleDisplay()->IsAbsolutelyPositioned()) {
|
||||
// It's not an absolute or fixed positioned frame, so it
|
||||
// must be a float!
|
||||
// XXX This is a lame-o way of detecting a float, but it's the only way
|
||||
// apparently
|
||||
if (!head) {
|
||||
head = current = outOfFlowFrame;
|
||||
} else {
|
||||
current->SetNextSibling(outOfFlowFrame);
|
||||
current = outOfFlowFrame;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// XXXldb What about a placeholder within an inline or block descendant?
|
||||
frame = frame->GetNextSibling();
|
||||
}
|
||||
|
||||
if (current) {
|
||||
current->SetNextSibling(nsnull);
|
||||
nsFrameList* frameList = new nsFrameList(head);
|
||||
if (frameList) {
|
||||
SetOverflowOutOfFlows(frameList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// XXX keep the text-run data in the first-in-flow of the block
|
||||
|
|
|
@ -56,10 +56,11 @@ class nsIntervalSet;
|
|||
* Child list name indices
|
||||
* @see #GetAdditionalChildListName()
|
||||
*/
|
||||
#define NS_BLOCK_FRAME_FLOAT_LIST_INDEX 0
|
||||
#define NS_BLOCK_FRAME_BULLET_LIST_INDEX 1
|
||||
#define NS_BLOCK_FRAME_OVERFLOW_LIST_INDEX 2
|
||||
#define NS_BLOCK_FRAME_ABSOLUTE_LIST_INDEX 3
|
||||
#define NS_BLOCK_FRAME_FLOAT_LIST_INDEX 0
|
||||
#define NS_BLOCK_FRAME_BULLET_LIST_INDEX 1
|
||||
#define NS_BLOCK_FRAME_OVERFLOW_LIST_INDEX 2
|
||||
#define NS_BLOCK_FRAME_OVERFLOW_OOF_LIST_INDEX 3
|
||||
#define NS_BLOCK_FRAME_ABSOLUTE_LIST_INDEX 4
|
||||
#define NS_BLOCK_FRAME_LAST_LIST_INDEX NS_BLOCK_FRAME_ABSOLUTE_LIST_INDEX
|
||||
|
||||
#define nsBlockFrameSuper nsHTMLContainerFrame
|
||||
|
@ -542,16 +543,17 @@ protected:
|
|||
|
||||
nsLineList* GetOverflowLines(nsIPresContext* aPresContext,
|
||||
PRBool aRemoveProperty) const;
|
||||
|
||||
nsresult SetOverflowLines(nsIPresContext* aPresContext,
|
||||
nsLineList* aOverflowLines);
|
||||
|
||||
nsFrameList* GetOverflowPlaceholders(nsIPresContext* aPresContext,
|
||||
PRBool aRemoveProperty) const;
|
||||
|
||||
nsresult SetOverflowPlaceholders(nsIPresContext* aPresContext,
|
||||
nsFrameList* aOverflowPlaceholders);
|
||||
|
||||
nsFrameList* GetOverflowOutOfFlows(PRBool aRemoveProperty) const;
|
||||
nsresult SetOverflowOutOfFlows(nsFrameList* aFloaters);
|
||||
|
||||
nsIFrame* LastChild();
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
|
|
|
@ -304,6 +304,11 @@ nsBlockFrame::Destroy(nsIPresContext* aPresContext)
|
|||
if (overflowLines) {
|
||||
nsLineBox::DeleteLineList(aPresContext, *overflowLines);
|
||||
}
|
||||
nsFrameList* overflowOutOfFlows = GetOverflowOutOfFlows(PR_TRUE);
|
||||
if (overflowOutOfFlows) {
|
||||
overflowOutOfFlows->DestroyFrames(aPresContext);
|
||||
delete overflowOutOfFlows;
|
||||
}
|
||||
|
||||
return nsBlockFrameSuper::Destroy(aPresContext);
|
||||
}
|
||||
|
@ -477,6 +482,10 @@ nsBlockFrame::GetFirstChild(nsIAtom* aListName) const
|
|||
nsLineList* overflowLines = GetOverflowLines(GetPresContext(), PR_FALSE);
|
||||
return overflowLines ? overflowLines->front()->mFirstChild : nsnull;
|
||||
}
|
||||
else if (aListName == nsLayoutAtoms::overflowOutOfFlowList) {
|
||||
nsFrameList* oof = GetOverflowOutOfFlows(PR_FALSE);
|
||||
return oof ? oof->FirstChild() : nsnull;
|
||||
}
|
||||
else if (aListName == nsLayoutAtoms::floatList) {
|
||||
return mFloats.FirstChild();
|
||||
}
|
||||
|
@ -498,6 +507,8 @@ nsBlockFrame::GetAdditionalChildListName(PRInt32 aIndex) const
|
|||
return nsLayoutAtoms::bulletList;
|
||||
case NS_BLOCK_FRAME_OVERFLOW_LIST_INDEX:
|
||||
return nsLayoutAtoms::overflowList;
|
||||
case NS_BLOCK_FRAME_OVERFLOW_OOF_LIST_INDEX:
|
||||
return nsLayoutAtoms::overflowOutOfFlowList;
|
||||
case NS_BLOCK_FRAME_ABSOLUTE_LIST_INDEX:
|
||||
return mAbsoluteContainer.GetChildListName();
|
||||
default:
|
||||
|
@ -4205,7 +4216,6 @@ nsBlockFrame::PushLines(nsBlockReflowState& aState,
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
// The overflowLines property is stored as a pointer to a line list,
|
||||
// which must be deleted. However, the following functions all maintain
|
||||
// the invariant that the property is never set if the list is empty.
|
||||
|
@ -4240,26 +4250,6 @@ nsBlockFrame::DrainOverflowLines(nsIPresContext* aPresContext)
|
|||
// present in the lines, so their views can be reparented?
|
||||
nsHTMLContainerFrame::ReparentFrameView(aPresContext, frame, prevBlock, this);
|
||||
|
||||
// If the frame we are looking at is a placeholder for a float, we
|
||||
// need to reparent both it's out-of-flow frame and any views it has.
|
||||
//
|
||||
// Note: A floating table (example: style="position: relative; float: right")
|
||||
// is an example of an out-of-flow frame with a view
|
||||
|
||||
// XXXldb What about a placeholder within an inline or block descendant?
|
||||
|
||||
if (nsLayoutAtoms::placeholderFrame == frame->GetType()) {
|
||||
nsIFrame *outOfFlowFrame =
|
||||
NS_STATIC_CAST(nsPlaceholderFrame*, frame)->GetOutOfFlowFrame();
|
||||
if (!outOfFlowFrame->GetStyleDisplay()->IsAbsolutelyPositioned()) {
|
||||
// It's not an absolute or fixed positioned frame, so it
|
||||
// must be a float!
|
||||
outOfFlowFrame->SetParent(this);
|
||||
nsHTMLContainerFrame::ReparentFrameView(aPresContext,
|
||||
outOfFlowFrame, prevBlock, this);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the next frame
|
||||
lastFrame = frame;
|
||||
frame = frame->GetNextSibling();
|
||||
|
@ -4275,6 +4265,20 @@ nsBlockFrame::DrainOverflowLines(nsIPresContext* aPresContext)
|
|||
mLines.splice(mLines.begin(), *overflowLines);
|
||||
NS_ASSERTION(overflowLines->empty(), "splice should empty list");
|
||||
delete overflowLines;
|
||||
|
||||
// Out-of-flow floats need to be reparented too.
|
||||
nsFrameList* overflowOutOfFlows = prevBlock->GetOverflowOutOfFlows(PR_TRUE);
|
||||
if (overflowOutOfFlows) {
|
||||
for (nsIFrame* f = overflowOutOfFlows->FirstChild(); f;
|
||||
f = f->GetNextSibling()) {
|
||||
f->SetParent(this);
|
||||
|
||||
// When pushing and pulling frames we need to check for whether any
|
||||
// views need to be reparented
|
||||
nsHTMLContainerFrame::ReparentFrameView(aPresContext, f, prevBlock, this);
|
||||
}
|
||||
delete overflowOutOfFlows;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4295,6 +4299,14 @@ nsBlockFrame::DrainOverflowLines(nsIPresContext* aPresContext)
|
|||
mLines.splice(mLines.end(), *overflowLines);
|
||||
drained = PR_TRUE;
|
||||
delete overflowLines;
|
||||
|
||||
// Likewise, drain our own overflow out-of-flows. We don't need to
|
||||
// reparent them since they're already our children. We don't need
|
||||
// to put them on any child list since BuildFloatList will put
|
||||
// them on some child list. All we need to do is remove the
|
||||
// property.
|
||||
nsFrameList* overflowOutOfFlows = GetOverflowOutOfFlows(PR_TRUE);
|
||||
delete overflowOutOfFlows;
|
||||
}
|
||||
return drained;
|
||||
}
|
||||
|
@ -4341,6 +4353,36 @@ nsBlockFrame::SetOverflowLines(nsIPresContext* aPresContext,
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsFrameList*
|
||||
nsBlockFrame::GetOverflowOutOfFlows(PRBool aRemoveProperty) const
|
||||
{
|
||||
return NS_STATIC_CAST(nsFrameList*,
|
||||
GetProperty(GetPresContext(), nsLayoutAtoms::overflowOutOfFlowsProperty,
|
||||
aRemoveProperty));
|
||||
}
|
||||
|
||||
// Destructor function for the overflowPlaceholders frame property
|
||||
static void
|
||||
DestroyOverflowOOFs(nsIPresContext* aPresContext,
|
||||
nsIFrame* aFrame,
|
||||
nsIAtom* aPropertyName,
|
||||
void* aPropertyValue)
|
||||
{
|
||||
NS_NOTREACHED("This helper method should never be called!");
|
||||
delete NS_STATIC_CAST(nsFrameList*, aPropertyValue);
|
||||
}
|
||||
|
||||
// This takes ownership of aFloaters.
|
||||
nsresult
|
||||
nsBlockFrame::SetOverflowOutOfFlows(nsFrameList* aOOFs)
|
||||
{
|
||||
nsresult rv = SetProperty(GetPresContext(), nsLayoutAtoms::overflowOutOfFlowsProperty,
|
||||
aOOFs, DestroyOverflowOOFs);
|
||||
// Verify that we didn't overwrite an existing overflow list
|
||||
NS_ASSERTION(rv != NS_IFRAME_MGR_PROP_OVERWRITTEN, "existing overflow float list");
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsFrameList*
|
||||
nsBlockFrame::GetOverflowPlaceholders(nsIPresContext* aPresContext,
|
||||
PRBool aRemoveProperty) const
|
||||
|
@ -6370,6 +6412,8 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
|
|||
void
|
||||
nsBlockFrame::BuildFloatList()
|
||||
{
|
||||
// Accumulate float list into mFloats.
|
||||
// Use the float cache to speed up searching the lines for floats.
|
||||
nsIFrame* head = nsnull;
|
||||
nsIFrame* current = nsnull;
|
||||
for (line_iterator line = begin_lines(), line_end = end_lines();
|
||||
|
@ -6379,10 +6423,9 @@ nsBlockFrame::BuildFloatList()
|
|||
nsFloatCache* fc = line->GetFirstFloat();
|
||||
while (fc) {
|
||||
nsIFrame* floatFrame = fc->mPlaceholder->GetOutOfFlowFrame();
|
||||
if (nsnull == head) {
|
||||
if (!head) {
|
||||
current = head = floatFrame;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
current->SetNextSibling(floatFrame);
|
||||
current = floatFrame;
|
||||
}
|
||||
|
@ -6392,10 +6435,51 @@ nsBlockFrame::BuildFloatList()
|
|||
}
|
||||
|
||||
// Terminate end of float list just in case a float was removed
|
||||
if (nsnull != current) {
|
||||
if (current) {
|
||||
current->SetNextSibling(nsnull);
|
||||
}
|
||||
mFloats.SetFrames(head);
|
||||
|
||||
// ensure that the floats in the overflow lines are put on a child list
|
||||
// and not dropped from the frame tree!
|
||||
// Note that overflow lines do not have any float cache set up for them,
|
||||
// because the float cache contains only laid-out floats
|
||||
nsLineList* overflowLines = GetOverflowLines(GetPresContext(), PR_FALSE);
|
||||
if (overflowLines) {
|
||||
head = nsnull;
|
||||
current = nsnull;
|
||||
|
||||
nsIFrame* frame = overflowLines->front()->mFirstChild;
|
||||
while (frame) {
|
||||
if (nsLayoutAtoms::placeholderFrame == frame->GetType()) {
|
||||
nsIFrame *outOfFlowFrame = NS_STATIC_CAST(nsPlaceholderFrame*, frame)->GetOutOfFlowFrame();
|
||||
if (outOfFlowFrame &&
|
||||
!outOfFlowFrame->GetStyleDisplay()->IsAbsolutelyPositioned()) {
|
||||
// It's not an absolute or fixed positioned frame, so it
|
||||
// must be a float!
|
||||
// XXX This is a lame-o way of detecting a float, but it's the only way
|
||||
// apparently
|
||||
if (!head) {
|
||||
head = current = outOfFlowFrame;
|
||||
} else {
|
||||
current->SetNextSibling(outOfFlowFrame);
|
||||
current = outOfFlowFrame;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// XXXldb What about a placeholder within an inline or block descendant?
|
||||
frame = frame->GetNextSibling();
|
||||
}
|
||||
|
||||
if (current) {
|
||||
current->SetNextSibling(nsnull);
|
||||
nsFrameList* frameList = new nsFrameList(head);
|
||||
if (frameList) {
|
||||
SetOverflowOutOfFlows(frameList);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// XXX keep the text-run data in the first-in-flow of the block
|
||||
|
|
|
@ -56,10 +56,11 @@ class nsIntervalSet;
|
|||
* Child list name indices
|
||||
* @see #GetAdditionalChildListName()
|
||||
*/
|
||||
#define NS_BLOCK_FRAME_FLOAT_LIST_INDEX 0
|
||||
#define NS_BLOCK_FRAME_BULLET_LIST_INDEX 1
|
||||
#define NS_BLOCK_FRAME_OVERFLOW_LIST_INDEX 2
|
||||
#define NS_BLOCK_FRAME_ABSOLUTE_LIST_INDEX 3
|
||||
#define NS_BLOCK_FRAME_FLOAT_LIST_INDEX 0
|
||||
#define NS_BLOCK_FRAME_BULLET_LIST_INDEX 1
|
||||
#define NS_BLOCK_FRAME_OVERFLOW_LIST_INDEX 2
|
||||
#define NS_BLOCK_FRAME_OVERFLOW_OOF_LIST_INDEX 3
|
||||
#define NS_BLOCK_FRAME_ABSOLUTE_LIST_INDEX 4
|
||||
#define NS_BLOCK_FRAME_LAST_LIST_INDEX NS_BLOCK_FRAME_ABSOLUTE_LIST_INDEX
|
||||
|
||||
#define nsBlockFrameSuper nsHTMLContainerFrame
|
||||
|
@ -542,16 +543,17 @@ protected:
|
|||
|
||||
nsLineList* GetOverflowLines(nsIPresContext* aPresContext,
|
||||
PRBool aRemoveProperty) const;
|
||||
|
||||
nsresult SetOverflowLines(nsIPresContext* aPresContext,
|
||||
nsLineList* aOverflowLines);
|
||||
|
||||
nsFrameList* GetOverflowPlaceholders(nsIPresContext* aPresContext,
|
||||
PRBool aRemoveProperty) const;
|
||||
|
||||
nsresult SetOverflowPlaceholders(nsIPresContext* aPresContext,
|
||||
nsFrameList* aOverflowPlaceholders);
|
||||
|
||||
nsFrameList* GetOverflowOutOfFlows(PRBool aRemoveProperty) const;
|
||||
nsresult SetOverflowOutOfFlows(nsFrameList* aFloaters);
|
||||
|
||||
nsIFrame* LastChild();
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
|
|
Загрузка…
Ссылка в новой задаче